@arronqzy/react-blueprint 1.0.22 → 1.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -104,6 +104,19 @@ useBlueprintPageLifecycle({
104
104
  | `BlueprintPanelToolbar` | 库、保存、同步、调试按钮 |
105
105
  | `BlueprintExecutionLogPanel` | 执行日志 |
106
106
 
107
+ ## 本地存储
108
+
109
+ 蓝图库、执行日志、接口集合存在 IndexedDB,函数最后一个参数都是 `nameSpace`:
110
+
111
+ | 数据 | 函数 |
112
+ |------|------|
113
+ | 蓝图库 | `listBlueprintLibrary` / `getBlueprintLibraryRecord` / `putBlueprintLibraryRecord` / `deleteBlueprintLibraryRecord` / `clearBlueprintLibrary` |
114
+ | 执行日志 | `listExecutionRunRecords` / `getExecutionRunRecord` / `putExecutionRunRecord` / `deleteExecutionRunRecord` / `clearAllExecutionRunRecords` / `purgeExecutionRunsOlderThan` / `trimExecutionRunRecordsToMax` / `downloadExecutionRunExport` |
115
+ | 执行日志保留策略 | `readExecutionLogSettings` / `writeExecutionLogSettings` / `DEFAULT_EXECUTION_LOG_SETTINGS` |
116
+ | 接口集合 | `listApiCollectionRecords` / `deleteApiCollection` / `clearApiCollections`(同时更新内存中的接口列表) |
117
+
118
+ 这一层不负责通知已挂载的视图面板。宿主清理数据请用 `@arronqzy/abuilder` / `@arronqzy/abuilder-vue` 导出的同名函数,删除蓝图库后面板会自动刷新。
119
+
107
120
  ## 依赖
108
121
 
109
122
  `@arronqzy/blueprint-dsl`、`@arronqzy/i18n`、`@arronqzy/react-rx-store`、`@arronqzy/ui`、`@xyflow/react`。
package/index.ts CHANGED
@@ -22,12 +22,19 @@ export type {
22
22
  } from "./src/hooks/useBlueprintDebugSession";
23
23
  export {
24
24
  listExecutionRunRecords,
25
+ getExecutionRunRecord,
25
26
  putExecutionRunRecord,
27
+ deleteExecutionRunRecord,
26
28
  purgeExecutionRunsOlderThan,
27
29
  clearAllExecutionRunRecords,
28
30
  trimExecutionRunRecordsToMax,
29
31
  downloadExecutionRunExport,
30
32
  } from "./src/library/execution-log-db";
33
+ export {
34
+ DEFAULT_EXECUTION_LOG_SETTINGS,
35
+ readExecutionLogSettings,
36
+ writeExecutionLogSettings,
37
+ } from "./src/library/execution-log-settings";
31
38
  export type { UseBlueprintPageLifecycleOptions } from "./src/hooks/useBlueprintPageLifecycle";
32
39
  export { useBlueprintPageLifecycle } from "./src/hooks/useBlueprintPageLifecycle";
33
40
  export { stopAllClockSchedules } from "@arronqzy/blueprint-dsl";
@@ -49,16 +56,24 @@ export {
49
56
  getApiCollectionById,
50
57
  getApiCollectionListItems,
51
58
  upsertApiCollectionFromJson,
59
+ putApiCollection,
52
60
  removeApiCollection,
61
+ deleteApiCollection,
62
+ clearApiCollections,
53
63
  subscribeApiCollections,
54
64
  useApiCollections,
55
65
  useApiCollectionListItems,
56
66
  } from "./src/library/api-collection-store";
67
+ export type {
68
+ UpsertApiCollectionInput,
69
+ UpsertApiCollectionResult,
70
+ } from "./src/library/api-collection-store";
57
71
  export {
58
72
  listApiCollectionRecords,
59
73
  getApiCollectionRecord,
60
74
  putApiCollectionRecord,
61
75
  deleteApiCollectionRecord,
76
+ clearApiCollectionRecords,
62
77
  } from "./src/library/api-collection-db";
63
78
  export { BlueprintLibrarySelect } from "./src/components/BlueprintLibrarySelect";
64
79
  export type { BlueprintLibrarySelectProps } from "./src/components/BlueprintLibrarySelect";
@@ -87,6 +102,7 @@ export {
87
102
  parseBlueprintImportFile,
88
103
  } from "./src/library/blueprint-io";
89
104
  export {
105
+ clearBlueprintLibrary,
90
106
  deleteBlueprintLibraryRecord,
91
107
  getBlueprintLibraryRecord,
92
108
  listBlueprintLibrary,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arronqzy/react-blueprint",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "",
5
5
  "files": [
6
6
  "index.ts",
@@ -18,9 +18,9 @@
18
18
  "dayjs": "^1.11.13",
19
19
  "react-dom": "^19",
20
20
  "@xyflow/react": "^12.9.3",
21
- "@arronqzy/blueprint-dsl": "1.0.17",
22
21
  "@arronqzy/react-rx-store": "1.1.8",
23
22
  "@arronqzy/ui": "1.0.10",
23
+ "@arronqzy/blueprint-dsl": "1.0.17",
24
24
  "@arronqzy/i18n": "0.1.17"
25
25
  },
26
26
  "devDependencies": {
@@ -34,8 +34,8 @@
34
34
  "eslint": "^8.57.0",
35
35
  "typescript": "^5.5.4",
36
36
  "vite": "^5.1.4",
37
- "@arronqzy/tailwind": "1.0.2",
38
37
  "@arronqzy/eslint-config": "0.0.0",
38
+ "@arronqzy/tailwind": "1.0.2",
39
39
  "@arronqzy/typescript-config": "1.0.0"
40
40
  },
41
41
  "keywords": [],
@@ -96,3 +96,7 @@ export async function deleteApiCollectionRecord(
96
96
  nameSpace
97
97
  );
98
98
  }
99
+
100
+ export async function clearApiCollectionRecords(nameSpace?: string | null): Promise<void> {
101
+ await runTransaction<undefined>("readwrite", (store) => store.clear(), nameSpace);
102
+ }
@@ -6,9 +6,11 @@ import {
6
6
  type ApiCollectionDocument,
7
7
  type ApiCollectionListItem,
8
8
  type ApiCollectionRecord,
9
+ normalizeAppNameSpace,
9
10
  } from "@arronqzy/blueprint-dsl";
10
11
 
11
12
  import {
13
+ clearApiCollectionRecords,
12
14
  deleteApiCollectionRecord,
13
15
  listApiCollectionRecords,
14
16
  putApiCollectionRecord,
@@ -68,18 +70,48 @@ export type UpsertApiCollectionInput = {
68
70
  persistLocal: boolean;
69
71
  /** 未写 document.name 时用文件名 */
70
72
  fallbackName?: string;
73
+ /** 省略时写入当前已 hydrate 的 nameSpace */
74
+ nameSpace?: string | null;
71
75
  };
72
76
 
73
77
  export type UpsertApiCollectionResult =
74
78
  | { ok: true; record: ApiCollectionRecord }
75
79
  | { ok: false; error: string };
76
80
 
81
+ function isCurrentNameSpace(nameSpace?: string | null): boolean {
82
+ return normalizeAppNameSpace(nameSpace) === normalizeAppNameSpace(nameSpaceRef);
83
+ }
84
+
85
+ /** 写入接口集合;persistLocal 时落 IndexedDB,同一 nameSpace 下刷新内存列表 */
86
+ export async function putApiCollection(
87
+ record: ApiCollectionRecord,
88
+ nameSpace?: string | null
89
+ ): Promise<ApiCollectionRecord> {
90
+ if (record.persistLocal) {
91
+ await putApiCollectionRecord(record, nameSpace);
92
+ } else if (isCurrentNameSpace(nameSpace)) {
93
+ const existing = records.find((item) => item.id === record.id);
94
+ if (existing?.persistLocal) {
95
+ await deleteApiCollectionRecord(record.id, nameSpace);
96
+ }
97
+ }
98
+ if (isCurrentNameSpace(nameSpace)) {
99
+ const next = records.filter((item) => item.id !== record.id);
100
+ next.push(record);
101
+ records = sortRecords(next);
102
+ emit();
103
+ }
104
+ return record;
105
+ }
106
+
77
107
  export async function upsertApiCollectionFromJson(
78
108
  input: UpsertApiCollectionInput
79
109
  ): Promise<UpsertApiCollectionResult> {
80
110
  const parsed = parseApiCollectionJson(input.rawJson);
81
111
  if (!parsed.ok) return parsed;
82
112
 
113
+ const targetNameSpace =
114
+ input.nameSpace !== undefined ? input.nameSpace : nameSpaceRef;
83
115
  const document: ApiCollectionDocument = {
84
116
  ...parsed.document,
85
117
  name:
@@ -88,11 +120,18 @@ export async function upsertApiCollectionFromJson(
88
120
  parsed.document.name,
89
121
  };
90
122
  const now = Date.now();
91
- const existing = input.id
123
+ const existingInMemory = input.id
92
124
  ? records.find((item) => item.id === input.id) ?? null
93
125
  : null;
126
+ const existingPersisted =
127
+ input.id && !isCurrentNameSpace(targetNameSpace)
128
+ ? await listApiCollectionRecords(targetNameSpace).then(
129
+ (list) => list.find((item) => item.id === input.id) ?? null
130
+ )
131
+ : null;
132
+ const existing = existingInMemory ?? existingPersisted;
94
133
  const record: ApiCollectionRecord = {
95
- id: existing?.id ?? createApiCollectionId(),
134
+ id: existing?.id ?? input.id ?? createApiCollectionId(),
96
135
  name: document.name,
97
136
  persistLocal: input.persistLocal,
98
137
  document,
@@ -101,16 +140,7 @@ export async function upsertApiCollectionFromJson(
101
140
  updatedAt: now,
102
141
  };
103
142
 
104
- if (record.persistLocal) {
105
- await putApiCollectionRecord(record, nameSpaceRef);
106
- } else if (existing?.persistLocal) {
107
- await deleteApiCollectionRecord(record.id, nameSpaceRef);
108
- }
109
-
110
- const next = records.filter((item) => item.id !== record.id);
111
- next.push(record);
112
- records = sortRecords(next);
113
- emit();
143
+ await putApiCollection(record, targetNameSpace);
114
144
  return { ok: true, record };
115
145
  }
116
146
 
@@ -127,6 +157,30 @@ export async function removeApiCollection(id: string): Promise<void> {
127
157
  emit();
128
158
  }
129
159
 
160
+ /** 按 nameSpace 删除接口集合;若该 nameSpace 正在被编辑器使用,内存列表同步移除 */
161
+ export async function deleteApiCollection(
162
+ id: string,
163
+ nameSpace?: string | null
164
+ ): Promise<void> {
165
+ await deleteApiCollectionRecord(id, nameSpace);
166
+ if (!isCurrentNameSpace(nameSpace)) return;
167
+ records = records.filter((item) => item.id !== id);
168
+ emit();
169
+ }
170
+
171
+ /** 清空该 nameSpace 下的接口集合(含仅存内存的集合),返回删除数量 */
172
+ export async function clearApiCollections(nameSpace?: string | null): Promise<number> {
173
+ const persisted = await listApiCollectionRecords(nameSpace);
174
+ await clearApiCollectionRecords(nameSpace);
175
+ const removedIds = new Set(persisted.map((item) => item.id));
176
+ if (isCurrentNameSpace(nameSpace)) {
177
+ records.forEach((item) => removedIds.add(item.id));
178
+ records = [];
179
+ emit();
180
+ }
181
+ return removedIds.size;
182
+ }
183
+
130
184
  export function useApiCollections(): ApiCollectionRecord[] {
131
185
  const [list, setList] = useState<ApiCollectionRecord[]>(() => records);
132
186
  useEffect(() => subscribeApiCollections(() => setList([...records])), []);
@@ -124,3 +124,10 @@ export async function deleteBlueprintLibraryRecord(
124
124
  ): Promise<void> {
125
125
  await runTransaction<undefined>("readwrite", (store) => store.delete(id), nameSpace);
126
126
  }
127
+
128
+ /** 清空该 nameSpace 下的蓝图库,返回删除数量 */
129
+ export async function clearBlueprintLibrary(nameSpace?: string | null): Promise<number> {
130
+ const count = await runTransaction<number>("readonly", (store) => store.count(), nameSpace);
131
+ await runTransaction<undefined>("readwrite", (store) => store.clear(), nameSpace);
132
+ return count;
133
+ }