@headless-tree/core 0.0.0-20250511185653 → 0.0.0-20250511190858

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/lib/cjs/core/create-tree.js +0 -9
  3. package/lib/cjs/features/async-data-loader/feature.js +20 -41
  4. package/lib/cjs/features/async-data-loader/types.d.ts +4 -4
  5. package/lib/cjs/features/main/types.d.ts +0 -2
  6. package/lib/cjs/features/sync-data-loader/feature.js +2 -0
  7. package/lib/cjs/index.d.ts +0 -2
  8. package/lib/cjs/index.js +0 -2
  9. package/lib/cjs/types/core.d.ts +1 -2
  10. package/lib/esm/core/create-tree.js +0 -9
  11. package/lib/esm/features/async-data-loader/feature.js +20 -41
  12. package/lib/esm/features/async-data-loader/types.d.ts +4 -4
  13. package/lib/esm/features/main/types.d.ts +0 -2
  14. package/lib/esm/features/sync-data-loader/feature.js +2 -0
  15. package/lib/esm/index.d.ts +0 -2
  16. package/lib/esm/index.js +0 -2
  17. package/lib/esm/types/core.d.ts +1 -2
  18. package/package.json +1 -1
  19. package/src/core/create-tree.ts +0 -13
  20. package/src/features/async-data-loader/feature.ts +24 -35
  21. package/src/features/async-data-loader/types.ts +4 -4
  22. package/src/features/main/types.ts +0 -2
  23. package/src/features/sync-data-loader/feature.ts +3 -0
  24. package/src/features/tree/types.ts +1 -1
  25. package/src/index.ts +0 -2
  26. package/src/types/core.ts +0 -2
  27. package/lib/cjs/features/checkboxes/feature.d.ts +0 -2
  28. package/lib/cjs/features/checkboxes/feature.js +0 -94
  29. package/lib/cjs/features/checkboxes/types.d.ts +0 -26
  30. package/lib/cjs/features/checkboxes/types.js +0 -9
  31. package/lib/esm/features/checkboxes/feature.d.ts +0 -2
  32. package/lib/esm/features/checkboxes/feature.js +0 -91
  33. package/lib/esm/features/checkboxes/types.d.ts +0 -26
  34. package/lib/esm/features/checkboxes/types.js +0 -6
  35. package/src/features/checkboxes/checkboxes.spec.ts +0 -134
  36. package/src/features/checkboxes/feature.ts +0 -119
  37. package/src/features/checkboxes/types.ts +0 -28
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @headless-tree/core
2
2
 
3
- ## 0.0.0-20250511185653
3
+ ## 0.0.0-20250511190858
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -100,15 +100,6 @@ const createTree = (initialConfig) => {
100
100
  const externalStateSetter = config[stateHandlerNames[stateName]];
101
101
  externalStateSetter === null || externalStateSetter === void 0 ? void 0 : externalStateSetter(state[stateName]);
102
102
  },
103
- buildItemInstance: ({}, itemId) => {
104
- const [instance, finalizeInstance] = buildInstance(features, "itemInstance", (instance) => ({
105
- item: instance,
106
- tree: treeInstance,
107
- itemId,
108
- }));
109
- finalizeInstance();
110
- return instance;
111
- },
112
103
  // TODO rebuildSubTree: (itemId: string) => void;
113
104
  rebuildTree: () => {
114
105
  var _a;
@@ -20,44 +20,41 @@ const getDataRef = (tree) => {
20
20
  return dataRef;
21
21
  };
22
22
  const loadItemData = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
23
- var _a, _b, _c;
23
+ var _a;
24
24
  const config = tree.getConfig();
25
25
  const dataRef = getDataRef(tree);
26
26
  const item = yield config.dataLoader.getItem(itemId);
27
27
  dataRef.current.itemData[itemId] = item;
28
28
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, itemId, item);
29
29
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => id !== itemId));
30
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[itemId].forEach((cb) => cb());
31
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[itemId];
30
+ return item;
32
31
  });
33
32
  const loadChildrenIds = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
34
- var _a, _b, _c, _d, _e;
33
+ var _a, _b;
35
34
  const config = tree.getConfig();
36
35
  const dataRef = getDataRef(tree);
36
+ let childrenIds;
37
37
  if ("getChildrenWithData" in config.dataLoader) {
38
38
  const children = yield config.dataLoader.getChildrenWithData(itemId);
39
- const childrenIds = children.map((c) => c.id);
39
+ childrenIds = children.map((c) => c.id);
40
40
  dataRef.current.childrenIds[itemId] = childrenIds;
41
41
  children.forEach(({ id, data }) => {
42
- var _a, _b, _c;
42
+ var _a;
43
43
  dataRef.current.itemData[id] = data;
44
44
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, id, data);
45
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[id].forEach((cb) => cb());
46
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[id];
47
45
  });
48
46
  (_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
49
47
  tree.rebuildTree();
50
48
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => !childrenIds.includes(id)));
51
49
  }
52
50
  else {
53
- const childrenIds = yield config.dataLoader.getChildren(itemId);
51
+ childrenIds = yield config.dataLoader.getChildren(itemId);
54
52
  dataRef.current.childrenIds[itemId] = childrenIds;
55
53
  (_b = config.onLoadedChildren) === null || _b === void 0 ? void 0 : _b.call(config, itemId, childrenIds);
56
54
  tree.rebuildTree();
57
55
  }
58
56
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId));
59
- (_d = (_c = dataRef.current.awaitingItemChildrensLoading) === null || _c === void 0 ? void 0 : _c[itemId]) === null || _d === void 0 ? void 0 : _d.forEach((cb) => cb());
60
- (_e = dataRef.current.awaitingItemChildrensLoading) === null || _e === void 0 ? true : delete _e[itemId];
57
+ return childrenIds;
61
58
  });
62
59
  exports.asyncDataLoaderFeature = {
63
60
  key: "async-data-loader",
@@ -68,42 +65,24 @@ exports.asyncDataLoaderFeature = {
68
65
  loadingItemChildrens: "setLoadingItemChildrens",
69
66
  },
70
67
  treeInstance: {
71
- waitForItemDataLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
72
- tree.retrieveItemData(itemId);
73
- if (!tree.getState().loadingItemData.includes(itemId)) {
74
- return;
75
- }
76
- yield new Promise((resolve) => {
77
- var _a, _b;
78
- var _c, _d;
79
- const dataRef = tree.getDataRef();
80
- (_a = (_c = dataRef.current).awaitingItemDataLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemDataLoading = {});
81
- (_b = (_d = dataRef.current.awaitingItemDataLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
82
- dataRef.current.awaitingItemDataLoading[itemId].push(resolve);
83
- });
68
+ waitForItemDataLoaded: ({ tree }, itemId) => tree.loadItemData(itemId),
69
+ waitForItemChildrenLoaded: ({ tree }, itemId) => tree.loadChildrenIds(itemId),
70
+ loadItemData: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
71
+ var _b;
72
+ return ((_b = getDataRef(tree).current.itemData[itemId]) !== null && _b !== void 0 ? _b : (yield loadItemData(tree, itemId)));
84
73
  }),
85
- waitForItemChildrenLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
86
- tree.retrieveChildrenIds(itemId);
87
- if (!tree.getState().loadingItemChildrens.includes(itemId)) {
88
- return;
89
- }
90
- yield new Promise((resolve) => {
91
- var _a, _b;
92
- var _c, _d;
93
- const dataRef = tree.getDataRef();
94
- (_a = (_c = dataRef.current).awaitingItemChildrensLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemChildrensLoading = {});
95
- (_b = (_d = dataRef.current.awaitingItemChildrensLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
96
- dataRef.current.awaitingItemChildrensLoading[itemId].push(resolve);
97
- });
74
+ loadChildrenIds: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
75
+ var _b;
76
+ return ((_b = getDataRef(tree).current.childrenIds[itemId]) !== null && _b !== void 0 ? _b : (yield loadChildrenIds(tree, itemId)));
98
77
  }),
99
- retrieveItemData: ({ tree }, itemId, skipFetch = false) => {
78
+ retrieveItemData: ({ tree }, itemId) => {
100
79
  var _a, _b;
101
80
  const config = tree.getConfig();
102
81
  const dataRef = getDataRef(tree);
103
82
  if (dataRef.current.itemData[itemId]) {
104
83
  return dataRef.current.itemData[itemId];
105
84
  }
106
- if (!tree.getState().loadingItemData.includes(itemId) && !skipFetch) {
85
+ if (!tree.getState().loadingItemData.includes(itemId)) {
107
86
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
108
87
  ...loadingItemData,
109
88
  itemId,
@@ -112,12 +91,12 @@ exports.asyncDataLoaderFeature = {
112
91
  }
113
92
  return (_b = (_a = config.createLoadingItemData) === null || _a === void 0 ? void 0 : _a.call(config)) !== null && _b !== void 0 ? _b : null;
114
93
  },
115
- retrieveChildrenIds: ({ tree }, itemId, skipFetch = false) => {
94
+ retrieveChildrenIds: ({ tree }, itemId) => {
116
95
  const dataRef = getDataRef(tree);
117
96
  if (dataRef.current.childrenIds[itemId]) {
118
97
  return dataRef.current.childrenIds[itemId];
119
98
  }
120
- if (tree.getState().loadingItemChildrens.includes(itemId) || skipFetch) {
99
+ if (tree.getState().loadingItemChildrens.includes(itemId)) {
121
100
  return [];
122
101
  }
123
102
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => [...loadingItemChildrens, itemId]);
@@ -1,11 +1,8 @@
1
1
  import { SetStateFn } from "../../types/core";
2
2
  import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
3
- type AwaitingLoaderCallbacks = Record<string, (() => void)[]>;
4
3
  export interface AsyncDataLoaderDataRef<T = any> {
5
4
  itemData: Record<string, T>;
6
5
  childrenIds: Record<string, string[]>;
7
- awaitingItemDataLoading: AwaitingLoaderCallbacks;
8
- awaitingItemChildrensLoading: AwaitingLoaderCallbacks;
9
6
  }
10
7
  /**
11
8
  * @category Async Data Loader/General
@@ -27,8 +24,12 @@ export type AsyncDataLoaderFeatureDef<T> = {
27
24
  onLoadedChildren?: (itemId: string, childrenIds: string[]) => void;
28
25
  };
29
26
  treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"] & {
27
+ /** @deprecated use loadItemData instead */
30
28
  waitForItemDataLoaded: (itemId: string) => Promise<void>;
29
+ /** @deprecated use loadChildrenIds instead */
31
30
  waitForItemChildrenLoaded: (itemId: string) => Promise<void>;
31
+ loadItemData: (itemId: string) => Promise<T>;
32
+ loadChildrenIds: (itemId: string) => Promise<string[]>;
32
33
  };
33
34
  itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
34
35
  /** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible
@@ -44,4 +45,3 @@ export type AsyncDataLoaderFeatureDef<T> = {
44
45
  };
45
46
  hotkeys: SyncDataLoaderFeatureDef<T>["hotkeys"];
46
47
  };
47
- export {};
@@ -17,8 +17,6 @@ export type MainFeatureDef<T = any> = {
17
17
  treeInstance: {
18
18
  /** @internal */
19
19
  applySubStateUpdate: <K extends keyof TreeState<any>>(stateName: K, updater: Updater<TreeState<T>[K]>) => void;
20
- /** @internal */
21
- buildItemInstance: (itemId: string) => ItemInstance<T>;
22
20
  setState: SetStateFn<TreeState<T>>;
23
21
  getState: () => TreeState<T>;
24
22
  setConfig: SetStateFn<TreeConfig<T>>;
@@ -40,6 +40,8 @@ exports.syncDataLoaderFeature = {
40
40
  }
41
41
  return unpromise(dataLoader.getChildrenWithData(itemId)).map((c) => c.data);
42
42
  },
43
+ loadItemData: ({ tree }, itemId) => tree.retrieveItemData(itemId),
44
+ loadChildrenIds: ({ tree }, itemId) => tree.retrieveChildrenIds(itemId),
43
45
  },
44
46
  itemInstance: {
45
47
  isLoading: () => false,
@@ -5,7 +5,6 @@ export { MainFeatureDef, InstanceBuilder } from "./features/main/types";
5
5
  export * from "./features/drag-and-drop/types";
6
6
  export * from "./features/keyboard-drag-and-drop/types";
7
7
  export * from "./features/selection/types";
8
- export * from "./features/checkboxes/types";
9
8
  export * from "./features/async-data-loader/types";
10
9
  export * from "./features/sync-data-loader/types";
11
10
  export * from "./features/hotkeys-core/types";
@@ -14,7 +13,6 @@ export * from "./features/renaming/types";
14
13
  export * from "./features/expand-all/types";
15
14
  export * from "./features/prop-memoization/types";
16
15
  export * from "./features/selection/feature";
17
- export * from "./features/checkboxes/feature";
18
16
  export * from "./features/hotkeys-core/feature";
19
17
  export * from "./features/async-data-loader/feature";
20
18
  export * from "./features/sync-data-loader/feature";
package/lib/cjs/index.js CHANGED
@@ -20,7 +20,6 @@ __exportStar(require("./features/tree/types"), exports);
20
20
  __exportStar(require("./features/drag-and-drop/types"), exports);
21
21
  __exportStar(require("./features/keyboard-drag-and-drop/types"), exports);
22
22
  __exportStar(require("./features/selection/types"), exports);
23
- __exportStar(require("./features/checkboxes/types"), exports);
24
23
  __exportStar(require("./features/async-data-loader/types"), exports);
25
24
  __exportStar(require("./features/sync-data-loader/types"), exports);
26
25
  __exportStar(require("./features/hotkeys-core/types"), exports);
@@ -29,7 +28,6 @@ __exportStar(require("./features/renaming/types"), exports);
29
28
  __exportStar(require("./features/expand-all/types"), exports);
30
29
  __exportStar(require("./features/prop-memoization/types"), exports);
31
30
  __exportStar(require("./features/selection/feature"), exports);
32
- __exportStar(require("./features/checkboxes/feature"), exports);
33
31
  __exportStar(require("./features/hotkeys-core/feature"), exports);
34
32
  __exportStar(require("./features/async-data-loader/feature"), exports);
35
33
  __exportStar(require("./features/sync-data-loader/feature"), exports);
@@ -10,7 +10,6 @@ import { RenamingFeatureDef } from "../features/renaming/types";
10
10
  import { ExpandAllFeatureDef } from "../features/expand-all/types";
11
11
  import { PropMemoizationFeatureDef } from "../features/prop-memoization/types";
12
12
  import { KeyboardDragAndDropFeatureDef } from "../features/keyboard-drag-and-drop/types";
13
- import { CheckboxesFeatureDef } from "../features/checkboxes/types";
14
13
  export type Updater<T> = T | ((old: T) => T);
15
14
  export type SetStateFn<T> = (updaterOrValue: Updater<T>) => void;
16
15
  export type FeatureDef = {
@@ -35,7 +34,7 @@ type MergedFeatures<F extends FeatureDef> = {
35
34
  itemInstance: UnionToIntersection<F["itemInstance"]>;
36
35
  hotkeys: F["hotkeys"];
37
36
  };
38
- export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | CheckboxesFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
37
+ export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
39
38
  type TreeStateType<T> = MergedFeatures<RegisteredFeatures<T>>["state"];
40
39
  export interface TreeState<T> extends TreeStateType<T> {
41
40
  }
@@ -97,15 +97,6 @@ export const createTree = (initialConfig) => {
97
97
  const externalStateSetter = config[stateHandlerNames[stateName]];
98
98
  externalStateSetter === null || externalStateSetter === void 0 ? void 0 : externalStateSetter(state[stateName]);
99
99
  },
100
- buildItemInstance: ({}, itemId) => {
101
- const [instance, finalizeInstance] = buildInstance(features, "itemInstance", (instance) => ({
102
- item: instance,
103
- tree: treeInstance,
104
- itemId,
105
- }));
106
- finalizeInstance();
107
- return instance;
108
- },
109
100
  // TODO rebuildSubTree: (itemId: string) => void;
110
101
  rebuildTree: () => {
111
102
  var _a;
@@ -17,44 +17,41 @@ const getDataRef = (tree) => {
17
17
  return dataRef;
18
18
  };
19
19
  const loadItemData = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
20
- var _a, _b, _c;
20
+ var _a;
21
21
  const config = tree.getConfig();
22
22
  const dataRef = getDataRef(tree);
23
23
  const item = yield config.dataLoader.getItem(itemId);
24
24
  dataRef.current.itemData[itemId] = item;
25
25
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, itemId, item);
26
26
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => id !== itemId));
27
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[itemId].forEach((cb) => cb());
28
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[itemId];
27
+ return item;
29
28
  });
30
29
  const loadChildrenIds = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
31
- var _a, _b, _c, _d, _e;
30
+ var _a, _b;
32
31
  const config = tree.getConfig();
33
32
  const dataRef = getDataRef(tree);
33
+ let childrenIds;
34
34
  if ("getChildrenWithData" in config.dataLoader) {
35
35
  const children = yield config.dataLoader.getChildrenWithData(itemId);
36
- const childrenIds = children.map((c) => c.id);
36
+ childrenIds = children.map((c) => c.id);
37
37
  dataRef.current.childrenIds[itemId] = childrenIds;
38
38
  children.forEach(({ id, data }) => {
39
- var _a, _b, _c;
39
+ var _a;
40
40
  dataRef.current.itemData[id] = data;
41
41
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, id, data);
42
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[id].forEach((cb) => cb());
43
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[id];
44
42
  });
45
43
  (_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
46
44
  tree.rebuildTree();
47
45
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => !childrenIds.includes(id)));
48
46
  }
49
47
  else {
50
- const childrenIds = yield config.dataLoader.getChildren(itemId);
48
+ childrenIds = yield config.dataLoader.getChildren(itemId);
51
49
  dataRef.current.childrenIds[itemId] = childrenIds;
52
50
  (_b = config.onLoadedChildren) === null || _b === void 0 ? void 0 : _b.call(config, itemId, childrenIds);
53
51
  tree.rebuildTree();
54
52
  }
55
53
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId));
56
- (_d = (_c = dataRef.current.awaitingItemChildrensLoading) === null || _c === void 0 ? void 0 : _c[itemId]) === null || _d === void 0 ? void 0 : _d.forEach((cb) => cb());
57
- (_e = dataRef.current.awaitingItemChildrensLoading) === null || _e === void 0 ? true : delete _e[itemId];
54
+ return childrenIds;
58
55
  });
59
56
  export const asyncDataLoaderFeature = {
60
57
  key: "async-data-loader",
@@ -65,42 +62,24 @@ export const asyncDataLoaderFeature = {
65
62
  loadingItemChildrens: "setLoadingItemChildrens",
66
63
  },
67
64
  treeInstance: {
68
- waitForItemDataLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
69
- tree.retrieveItemData(itemId);
70
- if (!tree.getState().loadingItemData.includes(itemId)) {
71
- return;
72
- }
73
- yield new Promise((resolve) => {
74
- var _a, _b;
75
- var _c, _d;
76
- const dataRef = tree.getDataRef();
77
- (_a = (_c = dataRef.current).awaitingItemDataLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemDataLoading = {});
78
- (_b = (_d = dataRef.current.awaitingItemDataLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
79
- dataRef.current.awaitingItemDataLoading[itemId].push(resolve);
80
- });
65
+ waitForItemDataLoaded: ({ tree }, itemId) => tree.loadItemData(itemId),
66
+ waitForItemChildrenLoaded: ({ tree }, itemId) => tree.loadChildrenIds(itemId),
67
+ loadItemData: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
68
+ var _b;
69
+ return ((_b = getDataRef(tree).current.itemData[itemId]) !== null && _b !== void 0 ? _b : (yield loadItemData(tree, itemId)));
81
70
  }),
82
- waitForItemChildrenLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
83
- tree.retrieveChildrenIds(itemId);
84
- if (!tree.getState().loadingItemChildrens.includes(itemId)) {
85
- return;
86
- }
87
- yield new Promise((resolve) => {
88
- var _a, _b;
89
- var _c, _d;
90
- const dataRef = tree.getDataRef();
91
- (_a = (_c = dataRef.current).awaitingItemChildrensLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemChildrensLoading = {});
92
- (_b = (_d = dataRef.current.awaitingItemChildrensLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
93
- dataRef.current.awaitingItemChildrensLoading[itemId].push(resolve);
94
- });
71
+ loadChildrenIds: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
72
+ var _b;
73
+ return ((_b = getDataRef(tree).current.childrenIds[itemId]) !== null && _b !== void 0 ? _b : (yield loadChildrenIds(tree, itemId)));
95
74
  }),
96
- retrieveItemData: ({ tree }, itemId, skipFetch = false) => {
75
+ retrieveItemData: ({ tree }, itemId) => {
97
76
  var _a, _b;
98
77
  const config = tree.getConfig();
99
78
  const dataRef = getDataRef(tree);
100
79
  if (dataRef.current.itemData[itemId]) {
101
80
  return dataRef.current.itemData[itemId];
102
81
  }
103
- if (!tree.getState().loadingItemData.includes(itemId) && !skipFetch) {
82
+ if (!tree.getState().loadingItemData.includes(itemId)) {
104
83
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
105
84
  ...loadingItemData,
106
85
  itemId,
@@ -109,12 +88,12 @@ export const asyncDataLoaderFeature = {
109
88
  }
110
89
  return (_b = (_a = config.createLoadingItemData) === null || _a === void 0 ? void 0 : _a.call(config)) !== null && _b !== void 0 ? _b : null;
111
90
  },
112
- retrieveChildrenIds: ({ tree }, itemId, skipFetch = false) => {
91
+ retrieveChildrenIds: ({ tree }, itemId) => {
113
92
  const dataRef = getDataRef(tree);
114
93
  if (dataRef.current.childrenIds[itemId]) {
115
94
  return dataRef.current.childrenIds[itemId];
116
95
  }
117
- if (tree.getState().loadingItemChildrens.includes(itemId) || skipFetch) {
96
+ if (tree.getState().loadingItemChildrens.includes(itemId)) {
118
97
  return [];
119
98
  }
120
99
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => [...loadingItemChildrens, itemId]);
@@ -1,11 +1,8 @@
1
1
  import { SetStateFn } from "../../types/core";
2
2
  import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
3
- type AwaitingLoaderCallbacks = Record<string, (() => void)[]>;
4
3
  export interface AsyncDataLoaderDataRef<T = any> {
5
4
  itemData: Record<string, T>;
6
5
  childrenIds: Record<string, string[]>;
7
- awaitingItemDataLoading: AwaitingLoaderCallbacks;
8
- awaitingItemChildrensLoading: AwaitingLoaderCallbacks;
9
6
  }
10
7
  /**
11
8
  * @category Async Data Loader/General
@@ -27,8 +24,12 @@ export type AsyncDataLoaderFeatureDef<T> = {
27
24
  onLoadedChildren?: (itemId: string, childrenIds: string[]) => void;
28
25
  };
29
26
  treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"] & {
27
+ /** @deprecated use loadItemData instead */
30
28
  waitForItemDataLoaded: (itemId: string) => Promise<void>;
29
+ /** @deprecated use loadChildrenIds instead */
31
30
  waitForItemChildrenLoaded: (itemId: string) => Promise<void>;
31
+ loadItemData: (itemId: string) => Promise<T>;
32
+ loadChildrenIds: (itemId: string) => Promise<string[]>;
32
33
  };
33
34
  itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
34
35
  /** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible
@@ -44,4 +45,3 @@ export type AsyncDataLoaderFeatureDef<T> = {
44
45
  };
45
46
  hotkeys: SyncDataLoaderFeatureDef<T>["hotkeys"];
46
47
  };
47
- export {};
@@ -17,8 +17,6 @@ export type MainFeatureDef<T = any> = {
17
17
  treeInstance: {
18
18
  /** @internal */
19
19
  applySubStateUpdate: <K extends keyof TreeState<any>>(stateName: K, updater: Updater<TreeState<T>[K]>) => void;
20
- /** @internal */
21
- buildItemInstance: (itemId: string) => ItemInstance<T>;
22
20
  setState: SetStateFn<TreeState<T>>;
23
21
  getState: () => TreeState<T>;
24
22
  setConfig: SetStateFn<TreeConfig<T>>;
@@ -37,6 +37,8 @@ export const syncDataLoaderFeature = {
37
37
  }
38
38
  return unpromise(dataLoader.getChildrenWithData(itemId)).map((c) => c.data);
39
39
  },
40
+ loadItemData: ({ tree }, itemId) => tree.retrieveItemData(itemId),
41
+ loadChildrenIds: ({ tree }, itemId) => tree.retrieveChildrenIds(itemId),
40
42
  },
41
43
  itemInstance: {
42
44
  isLoading: () => false,
@@ -5,7 +5,6 @@ export { MainFeatureDef, InstanceBuilder } from "./features/main/types";
5
5
  export * from "./features/drag-and-drop/types";
6
6
  export * from "./features/keyboard-drag-and-drop/types";
7
7
  export * from "./features/selection/types";
8
- export * from "./features/checkboxes/types";
9
8
  export * from "./features/async-data-loader/types";
10
9
  export * from "./features/sync-data-loader/types";
11
10
  export * from "./features/hotkeys-core/types";
@@ -14,7 +13,6 @@ export * from "./features/renaming/types";
14
13
  export * from "./features/expand-all/types";
15
14
  export * from "./features/prop-memoization/types";
16
15
  export * from "./features/selection/feature";
17
- export * from "./features/checkboxes/feature";
18
16
  export * from "./features/hotkeys-core/feature";
19
17
  export * from "./features/async-data-loader/feature";
20
18
  export * from "./features/sync-data-loader/feature";
package/lib/esm/index.js CHANGED
@@ -4,7 +4,6 @@ export * from "./features/tree/types";
4
4
  export * from "./features/drag-and-drop/types";
5
5
  export * from "./features/keyboard-drag-and-drop/types";
6
6
  export * from "./features/selection/types";
7
- export * from "./features/checkboxes/types";
8
7
  export * from "./features/async-data-loader/types";
9
8
  export * from "./features/sync-data-loader/types";
10
9
  export * from "./features/hotkeys-core/types";
@@ -13,7 +12,6 @@ export * from "./features/renaming/types";
13
12
  export * from "./features/expand-all/types";
14
13
  export * from "./features/prop-memoization/types";
15
14
  export * from "./features/selection/feature";
16
- export * from "./features/checkboxes/feature";
17
15
  export * from "./features/hotkeys-core/feature";
18
16
  export * from "./features/async-data-loader/feature";
19
17
  export * from "./features/sync-data-loader/feature";
@@ -10,7 +10,6 @@ import { RenamingFeatureDef } from "../features/renaming/types";
10
10
  import { ExpandAllFeatureDef } from "../features/expand-all/types";
11
11
  import { PropMemoizationFeatureDef } from "../features/prop-memoization/types";
12
12
  import { KeyboardDragAndDropFeatureDef } from "../features/keyboard-drag-and-drop/types";
13
- import { CheckboxesFeatureDef } from "../features/checkboxes/types";
14
13
  export type Updater<T> = T | ((old: T) => T);
15
14
  export type SetStateFn<T> = (updaterOrValue: Updater<T>) => void;
16
15
  export type FeatureDef = {
@@ -35,7 +34,7 @@ type MergedFeatures<F extends FeatureDef> = {
35
34
  itemInstance: UnionToIntersection<F["itemInstance"]>;
36
35
  hotkeys: F["hotkeys"];
37
36
  };
38
- export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | CheckboxesFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
37
+ export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
39
38
  type TreeStateType<T> = MergedFeatures<RegisteredFeatures<T>>["state"];
40
39
  export interface TreeState<T> extends TreeStateType<T> {
41
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-tree/core",
3
- "version": "0.0.0-20250511185653",
3
+ "version": "0.0.0-20250511190858",
4
4
  "type": "module",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/esm/index.js",
@@ -151,19 +151,6 @@ export const createTree = <T>(
151
151
  ] as Function;
152
152
  externalStateSetter?.(state[stateName]);
153
153
  },
154
- buildItemInstance: ({}, itemId) => {
155
- const [instance, finalizeInstance] = buildInstance(
156
- features,
157
- "itemInstance",
158
- (instance) => ({
159
- item: instance,
160
- tree: treeInstance,
161
- itemId,
162
- }),
163
- );
164
- finalizeInstance();
165
- return instance;
166
- },
167
154
  // TODO rebuildSubTree: (itemId: string) => void;
168
155
  rebuildTree: () => {
169
156
  rebuildItemMeta();
@@ -20,23 +20,21 @@ const loadItemData = async <T>(tree: TreeInstance<T>, itemId: string) => {
20
20
  loadingItemData.filter((id) => id !== itemId),
21
21
  );
22
22
 
23
- dataRef.current.awaitingItemDataLoading?.[itemId].forEach((cb) => cb());
24
- delete dataRef.current.awaitingItemDataLoading?.[itemId];
23
+ return item;
25
24
  };
26
25
 
27
26
  const loadChildrenIds = async <T>(tree: TreeInstance<T>, itemId: string) => {
28
27
  const config = tree.getConfig();
29
28
  const dataRef = getDataRef(tree);
29
+ let childrenIds: string[];
30
30
 
31
31
  if ("getChildrenWithData" in config.dataLoader) {
32
32
  const children = await config.dataLoader.getChildrenWithData(itemId);
33
- const childrenIds = children.map((c) => c.id);
33
+ childrenIds = children.map((c) => c.id);
34
34
  dataRef.current.childrenIds[itemId] = childrenIds;
35
35
  children.forEach(({ id, data }) => {
36
36
  dataRef.current.itemData[id] = data;
37
37
  config.onLoadedItem?.(id, data);
38
- dataRef.current.awaitingItemDataLoading?.[id].forEach((cb) => cb());
39
- delete dataRef.current.awaitingItemDataLoading?.[id];
40
38
  });
41
39
 
42
40
  config.onLoadedChildren?.(itemId, childrenIds);
@@ -45,7 +43,7 @@ const loadChildrenIds = async <T>(tree: TreeInstance<T>, itemId: string) => {
45
43
  loadingItemData.filter((id) => !childrenIds.includes(id)),
46
44
  );
47
45
  } else {
48
- const childrenIds = await config.dataLoader.getChildren(itemId);
46
+ childrenIds = await config.dataLoader.getChildren(itemId);
49
47
  dataRef.current.childrenIds[itemId] = childrenIds;
50
48
  config.onLoadedChildren?.(itemId, childrenIds);
51
49
  tree.rebuildTree();
@@ -55,8 +53,7 @@ const loadChildrenIds = async <T>(tree: TreeInstance<T>, itemId: string) => {
55
53
  loadingItemChildrens.filter((id) => id !== itemId),
56
54
  );
57
55
 
58
- dataRef.current.awaitingItemChildrensLoading?.[itemId]?.forEach((cb) => cb());
59
- delete dataRef.current.awaitingItemChildrensLoading?.[itemId];
56
+ return childrenIds;
60
57
  };
61
58
 
62
59
  export const asyncDataLoaderFeature: FeatureImplementation = {
@@ -80,33 +77,25 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
80
77
  },
81
78
 
82
79
  treeInstance: {
83
- waitForItemDataLoaded: async ({ tree }, itemId) => {
84
- tree.retrieveItemData(itemId);
85
- if (!tree.getState().loadingItemData.includes(itemId)) {
86
- return;
87
- }
88
- await new Promise<void>((resolve) => {
89
- const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
90
- dataRef.current.awaitingItemDataLoading ??= {};
91
- dataRef.current.awaitingItemDataLoading[itemId] ??= [];
92
- dataRef.current.awaitingItemDataLoading[itemId].push(resolve);
93
- });
94
- },
80
+ waitForItemDataLoaded: ({ tree }, itemId) => tree.loadItemData(itemId),
95
81
 
96
- waitForItemChildrenLoaded: async ({ tree }, itemId) => {
97
- tree.retrieveChildrenIds(itemId);
98
- if (!tree.getState().loadingItemChildrens.includes(itemId)) {
99
- return;
100
- }
101
- await new Promise<void>((resolve) => {
102
- const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
103
- dataRef.current.awaitingItemChildrensLoading ??= {};
104
- dataRef.current.awaitingItemChildrensLoading[itemId] ??= [];
105
- dataRef.current.awaitingItemChildrensLoading[itemId].push(resolve);
106
- });
82
+ waitForItemChildrenLoaded: ({ tree }, itemId) =>
83
+ tree.loadChildrenIds(itemId),
84
+
85
+ loadItemData: async ({ tree }, itemId) => {
86
+ return (
87
+ getDataRef(tree).current.itemData[itemId] ??
88
+ (await loadItemData(tree, itemId))
89
+ );
90
+ },
91
+ loadChildrenIds: async ({ tree }, itemId) => {
92
+ return (
93
+ getDataRef(tree).current.childrenIds[itemId] ??
94
+ (await loadChildrenIds(tree, itemId))
95
+ );
107
96
  },
108
97
 
109
- retrieveItemData: ({ tree }, itemId, skipFetch = false) => {
98
+ retrieveItemData: ({ tree }, itemId) => {
110
99
  const config = tree.getConfig();
111
100
  const dataRef = getDataRef(tree);
112
101
 
@@ -114,7 +103,7 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
114
103
  return dataRef.current.itemData[itemId];
115
104
  }
116
105
 
117
- if (!tree.getState().loadingItemData.includes(itemId) && !skipFetch) {
106
+ if (!tree.getState().loadingItemData.includes(itemId)) {
118
107
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
119
108
  ...loadingItemData,
120
109
  itemId,
@@ -126,13 +115,13 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
126
115
  return config.createLoadingItemData?.() ?? null;
127
116
  },
128
117
 
129
- retrieveChildrenIds: ({ tree }, itemId, skipFetch = false) => {
118
+ retrieveChildrenIds: ({ tree }, itemId) => {
130
119
  const dataRef = getDataRef(tree);
131
120
  if (dataRef.current.childrenIds[itemId]) {
132
121
  return dataRef.current.childrenIds[itemId];
133
122
  }
134
123
 
135
- if (tree.getState().loadingItemChildrens.includes(itemId) || skipFetch) {
124
+ if (tree.getState().loadingItemChildrens.includes(itemId)) {
136
125
  return [];
137
126
  }
138
127