@splicetree/core 0.1.0 → 0.2.0

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
@@ -1,7 +1,5 @@
1
1
  # @splicetree/core
2
2
 
3
- ## 简介
4
-
5
3
  SpliceTree 是一个 Headless 树运行时,面向扁平数据构建可操作的树结构,提供精简 API,并通过插件扩展搜索、拖拽、懒加载、键盘导航等能力。
6
4
 
7
5
  为扁平数据提供轻量、可扩展的树运行时。支持插件扩展事件与能力。
package/dist/index.d.ts CHANGED
@@ -97,15 +97,10 @@ interface SpliceTreeEvents {
97
97
  }
98
98
  /**
99
99
  * `createSpliceTree` 的选项
100
- * - `keyField`:主键字段名,默认 `'id'`
101
- * - `parentField`:父级字段名,默认 `'parent'`
102
100
  * - `plugins`:插件列表
103
- * - `defaultExpanded`:默认展开的节点 id 列表(或设为 true 表示全部展开)
104
- * - `defaultExpandedLevel`:默认展开的层级(或 `'deepest'` 表示展开到最深层)
105
101
  * - 其余键允许被插件进行选项扩展
106
102
  */
107
- interface SpliceTreeConfiguration {}
108
- interface UseSpliceTreeOptions<T = SpliceTreeData> {
103
+ interface SpliceTreeConfiguration {
109
104
  /**
110
105
  * 主键字段名
111
106
  * @default 'id'
@@ -116,10 +111,6 @@ interface UseSpliceTreeOptions<T = SpliceTreeData> {
116
111
  * @default 'parent'
117
112
  */
118
113
  parentField?: string;
119
- /**
120
- * 插件列表
121
- */
122
- plugins?: SpliceTreePlugin<T>[];
123
114
  /**
124
115
  * 默认展开的节点 ID 列表
125
116
  * 设为 true 表示默认展开所有节点
@@ -130,6 +121,12 @@ interface UseSpliceTreeOptions<T = SpliceTreeData> {
130
121
  * 设为 'deepest' 表示默认展开所有层级
131
122
  */
132
123
  defaultExpandedLevel?: number | 'deepest';
124
+ }
125
+ interface UseSpliceTreeOptions<T = SpliceTreeData> {
126
+ /**
127
+ * 插件列表
128
+ */
129
+ plugins?: SpliceTreePlugin<T>[];
133
130
  /**
134
131
  * 插件配置聚合入口(按插件名分类)
135
132
  */
@@ -214,6 +211,7 @@ interface SpliceTreeInstance<T = SpliceTreeData> {
214
211
  * @param beforeId 插入到指定兄弟节点之前(不传表示末尾)
215
212
  */
216
213
  moveNode: (id: string, newParentId: string | undefined, beforeId?: string) => void;
214
+ syncData: (next: T[]) => void;
217
215
  }
218
216
  /**
219
217
  * 插件上下文
package/dist/index.js CHANGED
@@ -327,8 +327,11 @@ function moveNode(ctx, id, newParentId, beforeId) {
327
327
  * - 提供插件扩展点(setup/extendNode)
328
328
  */
329
329
  function createSpliceTree(data, options = {}) {
330
- const keyField = options.keyField ?? "id";
331
- const parentField = options.parentField ?? "parent";
330
+ const cfg = options.configuration ?? {};
331
+ const keyField = cfg.keyField ?? "id";
332
+ const parentField = cfg.parentField ?? "parent";
333
+ const defaultExpanded = cfg.defaultExpanded;
334
+ const defaultExpandedLevel = cfg.defaultExpandedLevel;
332
335
  const events = createEmitter();
333
336
  const expandedKeys = createReactive(/* @__PURE__ */ new Set(), (payload) => {
334
337
  events.emit({
@@ -336,8 +339,8 @@ function createSpliceTree(data, options = {}) {
336
339
  keys: Array.from(payload.target)
337
340
  });
338
341
  });
339
- const { roots, map, parentCache, childrenCache } = buildTree(data, keyField, parentField, expandedKeys);
340
- initDefaultExpansion(map, expandedKeys, options.defaultExpanded, options.defaultExpandedLevel);
342
+ let { roots, map, parentCache, childrenCache } = buildTree(data, keyField, parentField, expandedKeys);
343
+ initDefaultExpansion(map, expandedKeys, defaultExpanded, defaultExpandedLevel);
341
344
  const emitVisibility = () => {
342
345
  events.emit({
343
346
  name: "visibility",
@@ -406,6 +409,22 @@ function createSpliceTree(data, options = {}) {
406
409
  expandedKeys,
407
410
  notify: emitVisibility
408
411
  }, id, newParentId, beforeId);
412
+ },
413
+ syncData(next) {
414
+ tree.data = next;
415
+ const built = buildTree(next, keyField, parentField, expandedKeys);
416
+ roots = built.roots;
417
+ map = built.map;
418
+ parentCache = built.parentCache;
419
+ childrenCache = built.childrenCache;
420
+ const validIds = new Set(map.keys());
421
+ const toDelete = [];
422
+ expandedKeys.forEach((id) => {
423
+ if (!validIds.has(id)) toDelete.push(id);
424
+ });
425
+ for (const id of toDelete) expandedKeys.delete(id);
426
+ applyNodeExtensions();
427
+ emitVisibility();
409
428
  }
410
429
  };
411
430
  const pluginCtx = {
@@ -417,15 +436,18 @@ function createSpliceTree(data, options = {}) {
417
436
  const api = plugin.setup?.(pluginCtx);
418
437
  Object.assign(tree, api);
419
438
  });
420
- if (options?.plugins?.length) for (const n of map.values()) for (const plugin of options.plugins) plugin.extendNode?.(n, pluginCtx);
421
- for (const node of map.values()) {
422
- node.isExpanded = () => tree.isExpanded(node.id);
423
- node.toggleExpand = (expand) => {
424
- if (expand === void 0) tree.toggleExpand(node.id);
425
- else if (expand) tree.expand(node.id);
426
- else tree.collapse(node.id);
427
- };
439
+ function applyNodeExtensions() {
440
+ if (options?.plugins?.length) for (const n of map.values()) for (const plugin of options.plugins) plugin.extendNode?.(n, pluginCtx);
441
+ for (const node of map.values()) {
442
+ node.isExpanded = () => tree.isExpanded(node.id);
443
+ node.toggleExpand = (expand) => {
444
+ if (expand === void 0) tree.toggleExpand(node.id);
445
+ else if (expand) tree.expand(node.id);
446
+ else tree.collapse(node.id);
447
+ };
448
+ }
428
449
  }
450
+ applyNodeExtensions();
429
451
  return tree;
430
452
  }
431
453
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@splicetree/core",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "author": {
6
6
  "email": "michael.cocova@gmail.com",
7
7
  "name": "Michael Cocova"