@headless-tree/core 0.0.0-20250506225933 → 0.0.0-20250507224143
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/CHANGELOG.md +7 -1
- package/lib/cjs/features/async-data-loader/feature.js +28 -10
- package/lib/cjs/features/sync-data-loader/feature.js +11 -9
- package/lib/cjs/features/sync-data-loader/types.d.ts +11 -2
- package/lib/esm/features/async-data-loader/feature.js +28 -10
- package/lib/esm/features/sync-data-loader/feature.js +11 -9
- package/lib/esm/features/sync-data-loader/types.d.ts +11 -2
- package/package.json +1 -1
- package/src/features/async-data-loader/async-data-loader.spec.ts +2 -0
- package/src/features/async-data-loader/feature.ts +24 -4
- package/src/features/sync-data-loader/feature.ts +13 -9
- package/src/features/sync-data-loader/types.ts +11 -4
package/CHANGELOG.md
CHANGED
|
@@ -76,11 +76,12 @@ exports.asyncDataLoaderFeature = {
|
|
|
76
76
|
return (_d = (_c = config.createLoadingItemData) === null || _c === void 0 ? void 0 : _c.call(config)) !== null && _d !== void 0 ? _d : null;
|
|
77
77
|
},
|
|
78
78
|
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
79
|
-
var _a;
|
|
80
|
-
var
|
|
79
|
+
var _a, _b;
|
|
80
|
+
var _c, _d;
|
|
81
81
|
const config = tree.getConfig();
|
|
82
82
|
const dataRef = tree.getDataRef();
|
|
83
|
-
(_a = (
|
|
83
|
+
(_a = (_c = dataRef.current).itemData) !== null && _a !== void 0 ? _a : (_c.itemData = {});
|
|
84
|
+
(_b = (_d = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_d.childrenIds = {});
|
|
84
85
|
if (dataRef.current.childrenIds[itemId]) {
|
|
85
86
|
return dataRef.current.childrenIds[itemId];
|
|
86
87
|
}
|
|
@@ -89,14 +90,31 @@ exports.asyncDataLoaderFeature = {
|
|
|
89
90
|
}
|
|
90
91
|
tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => [...loadingItemChildrens, itemId]);
|
|
91
92
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
-
var _a, _b, _c, _d;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
var _a, _b, _c, _d, _e;
|
|
94
|
+
if ("getChildrenWithData" in config.dataLoader) {
|
|
95
|
+
const children = yield config.dataLoader.getChildrenWithData(itemId);
|
|
96
|
+
const childrenIds = children.map((c) => c.id);
|
|
97
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
98
|
+
children.forEach(({ id, data }) => {
|
|
99
|
+
var _a, _b, _c;
|
|
100
|
+
dataRef.current.itemData[id] = data;
|
|
101
|
+
(_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, id, data);
|
|
102
|
+
(_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[id].forEach((cb) => cb());
|
|
103
|
+
(_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[id];
|
|
104
|
+
});
|
|
105
|
+
(_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
|
|
106
|
+
tree.rebuildTree();
|
|
107
|
+
tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => !childrenIds.includes(id)));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const childrenIds = yield config.dataLoader.getChildren(itemId);
|
|
111
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
112
|
+
(_b = config.onLoadedChildren) === null || _b === void 0 ? void 0 : _b.call(config, itemId, childrenIds);
|
|
113
|
+
tree.rebuildTree();
|
|
114
|
+
}
|
|
96
115
|
tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId));
|
|
97
|
-
|
|
98
|
-
(
|
|
99
|
-
(_d = dataRef.current.awaitingItemChildrensLoading) === null || _d === void 0 ? true : delete _d[itemId];
|
|
116
|
+
(_d = (_c = dataRef.current.awaitingItemChildrensLoading) === null || _c === void 0 ? void 0 : _c[itemId]) === null || _d === void 0 ? void 0 : _d.forEach((cb) => cb());
|
|
117
|
+
(_e = dataRef.current.awaitingItemChildrensLoading) === null || _e === void 0 ? true : delete _e[itemId];
|
|
100
118
|
}))();
|
|
101
119
|
return [];
|
|
102
120
|
},
|
|
@@ -13,6 +13,12 @@ exports.syncDataLoaderFeature = void 0;
|
|
|
13
13
|
const utils_1 = require("../../utils");
|
|
14
14
|
const errors_1 = require("../../utilities/errors");
|
|
15
15
|
const promiseErrorMessage = "sync dataLoader returned promise";
|
|
16
|
+
const unpromise = (data) => {
|
|
17
|
+
if (!data || (typeof data === "object" && "then" in data)) {
|
|
18
|
+
throw (0, errors_1.throwError)(promiseErrorMessage);
|
|
19
|
+
}
|
|
20
|
+
return data;
|
|
21
|
+
};
|
|
16
22
|
exports.syncDataLoaderFeature = {
|
|
17
23
|
key: "sync-data-loader",
|
|
18
24
|
getInitialState: (initialState) => (Object.assign({ loadingItemData: [], loadingItemChildrens: [] }, initialState)),
|
|
@@ -25,18 +31,14 @@ exports.syncDataLoaderFeature = {
|
|
|
25
31
|
waitForItemDataLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
26
32
|
waitForItemChildrenLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
27
33
|
retrieveItemData: ({ tree }, itemId) => {
|
|
28
|
-
|
|
29
|
-
if (typeof data === "object" && "then" in data) {
|
|
30
|
-
throw (0, errors_1.throwError)(promiseErrorMessage);
|
|
31
|
-
}
|
|
32
|
-
return data;
|
|
34
|
+
return unpromise(tree.getConfig().dataLoader.getItem(itemId));
|
|
33
35
|
},
|
|
34
36
|
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
37
|
-
|
|
37
|
+
const { dataLoader } = tree.getConfig();
|
|
38
|
+
if ("getChildren" in dataLoader) {
|
|
39
|
+
return unpromise(dataLoader.getChildren(itemId));
|
|
38
40
|
}
|
|
39
|
-
return data;
|
|
41
|
+
return unpromise(dataLoader.getChildrenWithData(itemId)).map((c) => c.data);
|
|
40
42
|
},
|
|
41
43
|
},
|
|
42
44
|
itemInstance: {
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type TreeDataLoader<T> = {
|
|
2
2
|
getItem: (itemId: string) => T | Promise<T>;
|
|
3
3
|
getChildren: (itemId: string) => string[] | Promise<string[]>;
|
|
4
|
-
}
|
|
4
|
+
} | {
|
|
5
|
+
getItem: (itemId: string) => T | Promise<T>;
|
|
6
|
+
getChildrenWithData: (itemId: string) => {
|
|
7
|
+
id: string;
|
|
8
|
+
data: T;
|
|
9
|
+
}[] | Promise<{
|
|
10
|
+
id: string;
|
|
11
|
+
data: T;
|
|
12
|
+
}[]>;
|
|
13
|
+
};
|
|
5
14
|
export type SyncDataLoaderFeatureDef<T> = {
|
|
6
15
|
state: {};
|
|
7
16
|
config: {
|
|
@@ -73,11 +73,12 @@ export const asyncDataLoaderFeature = {
|
|
|
73
73
|
return (_d = (_c = config.createLoadingItemData) === null || _c === void 0 ? void 0 : _c.call(config)) !== null && _d !== void 0 ? _d : null;
|
|
74
74
|
},
|
|
75
75
|
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
76
|
-
var _a;
|
|
77
|
-
var
|
|
76
|
+
var _a, _b;
|
|
77
|
+
var _c, _d;
|
|
78
78
|
const config = tree.getConfig();
|
|
79
79
|
const dataRef = tree.getDataRef();
|
|
80
|
-
(_a = (
|
|
80
|
+
(_a = (_c = dataRef.current).itemData) !== null && _a !== void 0 ? _a : (_c.itemData = {});
|
|
81
|
+
(_b = (_d = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_d.childrenIds = {});
|
|
81
82
|
if (dataRef.current.childrenIds[itemId]) {
|
|
82
83
|
return dataRef.current.childrenIds[itemId];
|
|
83
84
|
}
|
|
@@ -86,14 +87,31 @@ export const asyncDataLoaderFeature = {
|
|
|
86
87
|
}
|
|
87
88
|
tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => [...loadingItemChildrens, itemId]);
|
|
88
89
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
|
-
var _a, _b, _c, _d;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
var _a, _b, _c, _d, _e;
|
|
91
|
+
if ("getChildrenWithData" in config.dataLoader) {
|
|
92
|
+
const children = yield config.dataLoader.getChildrenWithData(itemId);
|
|
93
|
+
const childrenIds = children.map((c) => c.id);
|
|
94
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
95
|
+
children.forEach(({ id, data }) => {
|
|
96
|
+
var _a, _b, _c;
|
|
97
|
+
dataRef.current.itemData[id] = data;
|
|
98
|
+
(_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, id, data);
|
|
99
|
+
(_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[id].forEach((cb) => cb());
|
|
100
|
+
(_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[id];
|
|
101
|
+
});
|
|
102
|
+
(_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
|
|
103
|
+
tree.rebuildTree();
|
|
104
|
+
tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => !childrenIds.includes(id)));
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const childrenIds = yield config.dataLoader.getChildren(itemId);
|
|
108
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
109
|
+
(_b = config.onLoadedChildren) === null || _b === void 0 ? void 0 : _b.call(config, itemId, childrenIds);
|
|
110
|
+
tree.rebuildTree();
|
|
111
|
+
}
|
|
93
112
|
tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId));
|
|
94
|
-
|
|
95
|
-
(
|
|
96
|
-
(_d = dataRef.current.awaitingItemChildrensLoading) === null || _d === void 0 ? true : delete _d[itemId];
|
|
113
|
+
(_d = (_c = dataRef.current.awaitingItemChildrensLoading) === null || _c === void 0 ? void 0 : _c[itemId]) === null || _d === void 0 ? void 0 : _d.forEach((cb) => cb());
|
|
114
|
+
(_e = dataRef.current.awaitingItemChildrensLoading) === null || _e === void 0 ? true : delete _e[itemId];
|
|
97
115
|
}))();
|
|
98
116
|
return [];
|
|
99
117
|
},
|
|
@@ -10,6 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { makeStateUpdater } from "../../utils";
|
|
11
11
|
import { throwError } from "../../utilities/errors";
|
|
12
12
|
const promiseErrorMessage = "sync dataLoader returned promise";
|
|
13
|
+
const unpromise = (data) => {
|
|
14
|
+
if (!data || (typeof data === "object" && "then" in data)) {
|
|
15
|
+
throw throwError(promiseErrorMessage);
|
|
16
|
+
}
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
13
19
|
export const syncDataLoaderFeature = {
|
|
14
20
|
key: "sync-data-loader",
|
|
15
21
|
getInitialState: (initialState) => (Object.assign({ loadingItemData: [], loadingItemChildrens: [] }, initialState)),
|
|
@@ -22,18 +28,14 @@ export const syncDataLoaderFeature = {
|
|
|
22
28
|
waitForItemDataLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
23
29
|
waitForItemChildrenLoaded: () => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
24
30
|
retrieveItemData: ({ tree }, itemId) => {
|
|
25
|
-
|
|
26
|
-
if (typeof data === "object" && "then" in data) {
|
|
27
|
-
throw throwError(promiseErrorMessage);
|
|
28
|
-
}
|
|
29
|
-
return data;
|
|
31
|
+
return unpromise(tree.getConfig().dataLoader.getItem(itemId));
|
|
30
32
|
},
|
|
31
33
|
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
32
|
-
const
|
|
33
|
-
if (
|
|
34
|
-
|
|
34
|
+
const { dataLoader } = tree.getConfig();
|
|
35
|
+
if ("getChildren" in dataLoader) {
|
|
36
|
+
return unpromise(dataLoader.getChildren(itemId));
|
|
35
37
|
}
|
|
36
|
-
return data;
|
|
38
|
+
return unpromise(dataLoader.getChildrenWithData(itemId)).map((c) => c.data);
|
|
37
39
|
},
|
|
38
40
|
},
|
|
39
41
|
itemInstance: {
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type TreeDataLoader<T> = {
|
|
2
2
|
getItem: (itemId: string) => T | Promise<T>;
|
|
3
3
|
getChildren: (itemId: string) => string[] | Promise<string[]>;
|
|
4
|
-
}
|
|
4
|
+
} | {
|
|
5
|
+
getItem: (itemId: string) => T | Promise<T>;
|
|
6
|
+
getChildrenWithData: (itemId: string) => {
|
|
7
|
+
id: string;
|
|
8
|
+
data: T;
|
|
9
|
+
}[] | Promise<{
|
|
10
|
+
id: string;
|
|
11
|
+
data: T;
|
|
12
|
+
}[]>;
|
|
13
|
+
};
|
|
5
14
|
export type SyncDataLoaderFeatureDef<T> = {
|
|
6
15
|
state: {};
|
|
7
16
|
config: {
|
package/package.json
CHANGED
|
@@ -86,6 +86,7 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
|
|
|
86
86
|
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
87
87
|
const config = tree.getConfig();
|
|
88
88
|
const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
|
|
89
|
+
dataRef.current.itemData ??= {};
|
|
89
90
|
dataRef.current.childrenIds ??= {};
|
|
90
91
|
if (dataRef.current.childrenIds[itemId]) {
|
|
91
92
|
return dataRef.current.childrenIds[itemId];
|
|
@@ -101,15 +102,34 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
|
|
|
101
102
|
);
|
|
102
103
|
|
|
103
104
|
(async () => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
if ("getChildrenWithData" in config.dataLoader) {
|
|
106
|
+
const children = await config.dataLoader.getChildrenWithData(itemId);
|
|
107
|
+
const childrenIds = children.map((c) => c.id);
|
|
108
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
109
|
+
children.forEach(({ id, data }) => {
|
|
110
|
+
dataRef.current.itemData[id] = data;
|
|
111
|
+
config.onLoadedItem?.(id, data);
|
|
112
|
+
dataRef.current.awaitingItemDataLoading?.[id].forEach((cb) => cb());
|
|
113
|
+
delete dataRef.current.awaitingItemDataLoading?.[id];
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
config.onLoadedChildren?.(itemId, childrenIds);
|
|
117
|
+
tree.rebuildTree();
|
|
118
|
+
tree.applySubStateUpdate("loadingItemData", (loadingItemData) =>
|
|
119
|
+
loadingItemData.filter((id) => !childrenIds.includes(id)),
|
|
120
|
+
);
|
|
121
|
+
} else {
|
|
122
|
+
const childrenIds = await config.dataLoader.getChildren(itemId);
|
|
123
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
124
|
+
config.onLoadedChildren?.(itemId, childrenIds);
|
|
125
|
+
tree.rebuildTree();
|
|
126
|
+
}
|
|
127
|
+
|
|
107
128
|
tree.applySubStateUpdate(
|
|
108
129
|
"loadingItemChildrens",
|
|
109
130
|
(loadingItemChildrens) =>
|
|
110
131
|
loadingItemChildrens.filter((id) => id !== itemId),
|
|
111
132
|
);
|
|
112
|
-
tree.rebuildTree();
|
|
113
133
|
|
|
114
134
|
dataRef.current.awaitingItemChildrensLoading?.[itemId]?.forEach((cb) =>
|
|
115
135
|
cb(),
|
|
@@ -3,6 +3,12 @@ import { makeStateUpdater } from "../../utils";
|
|
|
3
3
|
import { throwError } from "../../utilities/errors";
|
|
4
4
|
|
|
5
5
|
const promiseErrorMessage = "sync dataLoader returned promise";
|
|
6
|
+
const unpromise = <T>(data: T | Promise<T>): T => {
|
|
7
|
+
if (!data || (typeof data === "object" && "then" in data)) {
|
|
8
|
+
throw throwError(promiseErrorMessage);
|
|
9
|
+
}
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
6
12
|
|
|
7
13
|
export const syncDataLoaderFeature: FeatureImplementation = {
|
|
8
14
|
key: "sync-data-loader",
|
|
@@ -29,19 +35,17 @@ export const syncDataLoaderFeature: FeatureImplementation = {
|
|
|
29
35
|
waitForItemChildrenLoaded: async () => {},
|
|
30
36
|
|
|
31
37
|
retrieveItemData: ({ tree }, itemId) => {
|
|
32
|
-
|
|
33
|
-
if (typeof data === "object" && "then" in data) {
|
|
34
|
-
throw throwError(promiseErrorMessage);
|
|
35
|
-
}
|
|
36
|
-
return data;
|
|
38
|
+
return unpromise(tree.getConfig().dataLoader.getItem(itemId));
|
|
37
39
|
},
|
|
38
40
|
|
|
39
41
|
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
|
|
42
|
+
const { dataLoader } = tree.getConfig();
|
|
43
|
+
if ("getChildren" in dataLoader) {
|
|
44
|
+
return unpromise(dataLoader.getChildren(itemId));
|
|
43
45
|
}
|
|
44
|
-
return
|
|
46
|
+
return unpromise(dataLoader.getChildrenWithData(itemId)).map(
|
|
47
|
+
(c) => c.data,
|
|
48
|
+
);
|
|
45
49
|
},
|
|
46
50
|
},
|
|
47
51
|
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export type TreeDataLoader<T> =
|
|
2
|
+
| {
|
|
3
|
+
getItem: (itemId: string) => T | Promise<T>;
|
|
4
|
+
getChildren: (itemId: string) => string[] | Promise<string[]>;
|
|
5
|
+
}
|
|
6
|
+
| {
|
|
7
|
+
getItem: (itemId: string) => T | Promise<T>;
|
|
8
|
+
getChildrenWithData: (
|
|
9
|
+
itemId: string,
|
|
10
|
+
) => { id: string; data: T }[] | Promise<{ id: string; data: T }[]>;
|
|
11
|
+
};
|
|
5
12
|
|
|
6
13
|
export type SyncDataLoaderFeatureDef<T> = {
|
|
7
14
|
state: {};
|