@headless-tree/core 0.0.0-20250916205935 → 0.0.0-20250918201417

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 CHANGED
@@ -1,6 +1,10 @@
1
1
  # @headless-tree/core
2
2
 
3
- ## 0.0.0-20250916205935
3
+ ## 0.0.0-20250918201417
4
+
5
+ ### Minor Changes
6
+
7
+ - cbeaba6: all state updates (like setSelectedItems) will not propagate while the component is unmounted. This happened before for `tree.setState()` calls directly, but not individual state atoms like `setSelectedItems`. When calling `createTree()` directly (instead of `useTree()`), `tree.setMounted(true)` needs to be called once after mount. No changes are necessary when using the React-based `useTree()` integration. (#158)
4
8
 
5
9
  ### Patch Changes
6
10
 
package/dist/index.d.mts CHANGED
@@ -184,6 +184,8 @@ type MainFeatureDef<T = any> = {
184
184
  rebuildTree: () => void;
185
185
  /** @deprecated Experimental feature, might get removed or changed in the future. */
186
186
  scheduleRebuildTree: () => void;
187
+ /** @internal */
188
+ setMounted: (isMounted: boolean) => void;
187
189
  };
188
190
  itemInstance: {
189
191
  registerElement: (element: HTMLElement | null) => void;
package/dist/index.d.ts CHANGED
@@ -184,6 +184,8 @@ type MainFeatureDef<T = any> = {
184
184
  rebuildTree: () => void;
185
185
  /** @deprecated Experimental feature, might get removed or changed in the future. */
186
186
  scheduleRebuildTree: () => void;
187
+ /** @internal */
188
+ setMounted: (isMounted: boolean) => void;
187
189
  };
188
190
  itemInstance: {
189
191
  registerElement: (element: HTMLElement | null) => void;
package/dist/index.js CHANGED
@@ -544,10 +544,29 @@ var createTree = (initialConfig) => {
544
544
  var _a2;
545
545
  (_a2 = config.setState) == null ? void 0 : _a2.call(config, state);
546
546
  },
547
+ setMounted: ({}, isMounted) => {
548
+ var _a2;
549
+ const ref = treeDataRef;
550
+ treeDataRef.current.isMounted = isMounted;
551
+ if (isMounted) {
552
+ (_a2 = ref.waitingForMount) == null ? void 0 : _a2.forEach((cb) => cb());
553
+ ref.waitingForMount = [];
554
+ }
555
+ },
547
556
  applySubStateUpdate: ({}, stateName, updater) => {
548
- state[stateName] = typeof updater === "function" ? updater(state[stateName]) : updater;
549
- const externalStateSetter = config[stateHandlerNames[stateName]];
550
- externalStateSetter == null ? void 0 : externalStateSetter(state[stateName]);
557
+ var _a2;
558
+ const apply = () => {
559
+ state[stateName] = typeof updater === "function" ? updater(state[stateName]) : updater;
560
+ const externalStateSetter = config[stateHandlerNames[stateName]];
561
+ externalStateSetter == null ? void 0 : externalStateSetter(state[stateName]);
562
+ };
563
+ const ref = treeDataRef.current;
564
+ if (ref.isMounted) {
565
+ apply();
566
+ } else {
567
+ (_a2 = ref.waitingForMount) != null ? _a2 : ref.waitingForMount = [];
568
+ ref.waitingForMount.push(apply);
569
+ }
551
570
  },
552
571
  // TODO rebuildSubTree: (itemId: string) => void;
553
572
  rebuildTree: () => {
package/dist/index.mjs CHANGED
@@ -500,10 +500,29 @@ var createTree = (initialConfig) => {
500
500
  var _a2;
501
501
  (_a2 = config.setState) == null ? void 0 : _a2.call(config, state);
502
502
  },
503
+ setMounted: ({}, isMounted) => {
504
+ var _a2;
505
+ const ref = treeDataRef;
506
+ treeDataRef.current.isMounted = isMounted;
507
+ if (isMounted) {
508
+ (_a2 = ref.waitingForMount) == null ? void 0 : _a2.forEach((cb) => cb());
509
+ ref.waitingForMount = [];
510
+ }
511
+ },
503
512
  applySubStateUpdate: ({}, stateName, updater) => {
504
- state[stateName] = typeof updater === "function" ? updater(state[stateName]) : updater;
505
- const externalStateSetter = config[stateHandlerNames[stateName]];
506
- externalStateSetter == null ? void 0 : externalStateSetter(state[stateName]);
513
+ var _a2;
514
+ const apply = () => {
515
+ state[stateName] = typeof updater === "function" ? updater(state[stateName]) : updater;
516
+ const externalStateSetter = config[stateHandlerNames[stateName]];
517
+ externalStateSetter == null ? void 0 : externalStateSetter(state[stateName]);
518
+ };
519
+ const ref = treeDataRef.current;
520
+ if (ref.isMounted) {
521
+ apply();
522
+ } else {
523
+ (_a2 = ref.waitingForMount) != null ? _a2 : ref.waitingForMount = [];
524
+ ref.waitingForMount.push(apply);
525
+ }
507
526
  },
508
527
  // TODO rebuildSubTree: (itemId: string) => void;
509
528
  rebuildTree: () => {
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "checkbox",
14
14
  "hook"
15
15
  ],
16
- "version": "0.0.0-20250916205935",
16
+ "version": "0.0.0-20250918201417",
17
17
  "main": "dist/index.d.ts",
18
18
  "module": "dist/index.mjs",
19
19
  "types": "dist/index.d.mts",
@@ -11,6 +11,7 @@ import { treeFeature } from "../features/tree/feature";
11
11
  import { ItemMeta } from "../features/tree/types";
12
12
  import { buildStaticInstance } from "./build-static-instance";
13
13
  import { throwError } from "../utilities/errors";
14
+ import type { TreeDataRef } from "../features/main/types";
14
15
 
15
16
  const verifyFeatures = (features: FeatureImplementation[] | undefined) => {
16
17
  const loadedFeatures = features?.map((feature) => feature.key);
@@ -161,17 +162,34 @@ export const createTree = <T>(
161
162
  config.setState?.(state); // TODO this cant be right... This doesnt allow external state updates
162
163
  // TODO this is never used, remove
163
164
  },
165
+ setMounted: ({}, isMounted) => {
166
+ const ref = treeDataRef as TreeDataRef;
167
+ treeDataRef.current.isMounted = isMounted;
168
+ if (isMounted) {
169
+ ref.waitingForMount?.forEach((cb) => cb());
170
+ ref.waitingForMount = [];
171
+ }
172
+ },
164
173
  applySubStateUpdate: <K extends keyof TreeState<any>>(
165
174
  {},
166
175
  stateName: K,
167
176
  updater: Updater<TreeState<T>[K]>,
168
177
  ) => {
169
- state[stateName] =
170
- typeof updater === "function" ? updater(state[stateName]) : updater;
171
- const externalStateSetter = config[
172
- stateHandlerNames[stateName]
173
- ] as Function;
174
- externalStateSetter?.(state[stateName]);
178
+ const apply = () => {
179
+ state[stateName] =
180
+ typeof updater === "function" ? updater(state[stateName]) : updater;
181
+ const externalStateSetter = config[
182
+ stateHandlerNames[stateName]
183
+ ] as Function;
184
+ externalStateSetter?.(state[stateName]);
185
+ };
186
+ const ref = treeDataRef.current as TreeDataRef;
187
+ if (ref.isMounted) {
188
+ apply();
189
+ } else {
190
+ ref.waitingForMount ??= [];
191
+ ref.waitingForMount.push(apply);
192
+ }
175
193
  },
176
194
  // TODO rebuildSubTree: (itemId: string) => void;
177
195
  rebuildTree: () => {
@@ -10,6 +10,11 @@ import {
10
10
  } from "../../types/core";
11
11
  import { ItemMeta } from "../tree/types";
12
12
 
13
+ export interface TreeDataRef {
14
+ isMounted?: boolean;
15
+ waitingForMount?: (() => void)[];
16
+ }
17
+
13
18
  export type InstanceTypeMap = {
14
19
  itemInstance: ItemInstance<any>;
15
20
  treeInstance: TreeInstance<any>;
@@ -51,6 +56,8 @@ export type MainFeatureDef<T = any> = {
51
56
  rebuildTree: () => void;
52
57
  /** @deprecated Experimental feature, might get removed or changed in the future. */
53
58
  scheduleRebuildTree: () => void;
59
+ /** @internal */
60
+ setMounted: (isMounted: boolean) => void;
54
61
  };
55
62
  itemInstance: {
56
63
  registerElement: (element: HTMLElement | null) => void;
@@ -78,6 +78,7 @@ export class TestTree<T = string> {
78
78
  get instance() {
79
79
  if (!this.treeInstance) {
80
80
  this.treeInstance = createTree(this.config);
81
+ this.treeInstance.setMounted(true);
81
82
  this.treeInstance.rebuildTree();
82
83
  }
83
84
  return this.treeInstance;