@gtkx/components 1.0.0-rc.4 → 1.1.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.
Files changed (86) hide show
  1. package/README.md +5 -5
  2. package/dist/column-view.d.ts +2 -2
  3. package/dist/column-view.d.ts.map +1 -1
  4. package/dist/column-view.js +14 -12
  5. package/dist/column-view.js.map +1 -1
  6. package/dist/grid-view.js +1 -1
  7. package/dist/grid-view.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal/cells.d.ts +31 -23
  12. package/dist/internal/cells.d.ts.map +1 -1
  13. package/dist/internal/cells.js +168 -77
  14. package/dist/internal/cells.js.map +1 -1
  15. package/dist/internal/collection-index.d.ts +8 -11
  16. package/dist/internal/collection-index.d.ts.map +1 -1
  17. package/dist/internal/collection-index.js +53 -73
  18. package/dist/internal/collection-index.js.map +1 -1
  19. package/dist/internal/collection-model.d.ts +24 -4
  20. package/dist/internal/collection-model.d.ts.map +1 -1
  21. package/dist/internal/collection-model.js +247 -96
  22. package/dist/internal/collection-model.js.map +1 -1
  23. package/dist/internal/collection.d.ts +8 -10
  24. package/dist/internal/collection.d.ts.map +1 -1
  25. package/dist/internal/collection.js +38 -48
  26. package/dist/internal/collection.js.map +1 -1
  27. package/dist/internal/controlled-sync.d.ts +11 -0
  28. package/dist/internal/controlled-sync.d.ts.map +1 -0
  29. package/dist/internal/controlled-sync.js +19 -0
  30. package/dist/internal/controlled-sync.js.map +1 -0
  31. package/dist/internal/drop-down.d.ts.map +1 -1
  32. package/dist/internal/drop-down.js +27 -15
  33. package/dist/internal/drop-down.js.map +1 -1
  34. package/dist/internal/expansion.d.ts +3 -2
  35. package/dist/internal/expansion.d.ts.map +1 -1
  36. package/dist/internal/expansion.js +73 -48
  37. package/dist/internal/expansion.js.map +1 -1
  38. package/dist/internal/keys.d.ts +5 -0
  39. package/dist/internal/keys.d.ts.map +1 -0
  40. package/dist/internal/keys.js +13 -0
  41. package/dist/internal/keys.js.map +1 -0
  42. package/dist/internal/selection.d.ts +3 -2
  43. package/dist/internal/selection.d.ts.map +1 -1
  44. package/dist/internal/selection.js +68 -35
  45. package/dist/internal/selection.js.map +1 -1
  46. package/dist/internal/slots.d.ts +10 -0
  47. package/dist/internal/slots.d.ts.map +1 -0
  48. package/dist/internal/slots.js +43 -0
  49. package/dist/internal/slots.js.map +1 -0
  50. package/dist/internal/tree-expansion.d.ts +19 -0
  51. package/dist/internal/tree-expansion.d.ts.map +1 -0
  52. package/dist/internal/tree-expansion.js +72 -0
  53. package/dist/internal/tree-expansion.js.map +1 -0
  54. package/dist/internal/tree-order.d.ts +26 -0
  55. package/dist/internal/tree-order.d.ts.map +1 -0
  56. package/dist/internal/tree-order.js +109 -0
  57. package/dist/internal/tree-order.js.map +1 -0
  58. package/dist/internal/use-collection.d.ts +1 -1
  59. package/dist/internal/use-collection.d.ts.map +1 -1
  60. package/dist/internal/use-collection.js +4 -4
  61. package/dist/internal/use-collection.js.map +1 -1
  62. package/dist/list-view.d.ts.map +1 -1
  63. package/dist/list-view.js +6 -6
  64. package/dist/list-view.js.map +1 -1
  65. package/dist/types.d.ts +72 -22
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js.map +1 -1
  68. package/package.json +17 -9
  69. package/src/column-view.tsx +28 -25
  70. package/src/grid-view.tsx +1 -1
  71. package/src/index.ts +3 -0
  72. package/src/internal/cells.tsx +339 -117
  73. package/src/internal/collection-index.ts +68 -92
  74. package/src/internal/collection-model.ts +327 -112
  75. package/src/internal/collection.ts +45 -65
  76. package/src/internal/controlled-sync.ts +34 -0
  77. package/src/internal/drop-down.tsx +41 -20
  78. package/src/internal/expansion.ts +95 -70
  79. package/src/internal/keys.ts +18 -0
  80. package/src/internal/selection.tsx +100 -51
  81. package/src/internal/slots.ts +67 -0
  82. package/src/internal/tree-expansion.ts +115 -0
  83. package/src/internal/tree-order.ts +208 -0
  84. package/src/internal/use-collection.tsx +5 -5
  85. package/src/list-view.tsx +14 -10
  86. package/src/types.ts +78 -20
@@ -1,20 +1,39 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as Gtk from "@gtkx/gi/gtk";
3
3
  import { GtkMultiSelection, GtkNoSelection, GtkSingleSelection } from "@gtkx/jsx/gtk";
4
- import { useEffectEvent, useLayoutEffect, useState } from "react";
5
- function getSelectedIds(selection, collection) {
4
+ import { useState } from "react";
5
+ import { isCollectionIdle } from "./collection.js";
6
+ import { useControlledSync } from "./controlled-sync.js";
7
+ import { joinParts } from "./keys.js";
8
+ function selectedPositions(selection) {
6
9
  const bitset = selection.getSelection();
7
10
  const size = Number(bitset.getSize());
8
- const ids = [];
11
+ const positions = [];
9
12
  for (let index = 0; index < size; index++) {
10
- pushId(collection.idAt(bitset.getNth(index)), ids);
13
+ positions.push(bitset.getNth(index));
14
+ }
15
+ return positions;
16
+ }
17
+ function idsAt(collection, positions) {
18
+ const ids = [];
19
+ for (const position of positions) {
20
+ const id = collection.idAt(position);
21
+ if (id !== null) {
22
+ ids.push(id);
23
+ }
11
24
  }
12
25
  return ids;
13
26
  }
14
- function pushId(id, ids) {
15
- if (id !== null) {
16
- ids.push(id);
27
+ function plannedPositions(context, ids) {
28
+ const { selection, collection } = context;
29
+ if (selection === null || selection instanceof Gtk.NoSelection) {
30
+ return null;
31
+ }
32
+ const positions = collection.positionsFor(ids);
33
+ if (ids.length > 0 && positions.length === 0) {
34
+ return null;
17
35
  }
36
+ return selection instanceof Gtk.SingleSelection ? positions.slice(0, 1) : positions;
18
37
  }
19
38
  function applySingleSelection(selection, positions) {
20
39
  const [first] = positions;
@@ -31,32 +50,24 @@ function applyMultiSelection(selection, positions) {
31
50
  }
32
51
  selection.setSelection(selected, Gtk.Bitset.newRange(0, selection.getNItems()));
33
52
  }
34
- function applySelection(selection, collection, ids) {
35
- if (selection instanceof Gtk.NoSelection) {
36
- return;
37
- }
38
- const positions = collection.positionsFor(ids);
39
- if (ids.length > 0 && positions.length === 0) {
40
- return;
41
- }
53
+ function applySelection(selection, positions) {
42
54
  if (selection instanceof Gtk.SingleSelection) {
43
55
  applySingleSelection(selection, positions);
44
56
  return;
45
57
  }
46
58
  applyMultiSelection(selection, positions);
47
59
  }
48
- function reportSelection(selection, collection, last, onSelectionChanged) {
49
- if (selection === null) {
50
- return;
51
- }
52
- const ids = getSelectedIds(selection, collection);
53
- const key = ids.join(" ");
54
- if (last.selection === selection && last.key === key) {
60
+ function reportSelection(context, ids) {
61
+ const key = joinParts(ids);
62
+ if (context.last.selection === context.selection && context.last.key === key) {
55
63
  return;
56
64
  }
57
- last.selection = selection;
58
- last.key = key;
59
- onSelectionChanged?.(ids);
65
+ context.last.selection = context.selection;
66
+ context.last.key = key;
67
+ context.onSelectionChanged?.(ids);
68
+ }
69
+ function hasSelectionDrifted(actual, planned) {
70
+ return actual.length !== planned.length || planned.some((position, index) => actual[index] !== position);
60
71
  }
61
72
  function selectionElement(mode, props) {
62
73
  if (mode === Gtk.SelectionMode.MULTIPLE) {
@@ -67,11 +78,31 @@ function selectionElement(mode, props) {
67
78
  }
68
79
  return _jsx(GtkSingleSelection, { ...props, autoselect: false, canUnselect: true });
69
80
  }
70
- function syncSelection(selection, collection, selectedIds) {
71
- if (selection === null || selectedIds == null) {
81
+ function applyControlledSelection(context, selectedIds) {
82
+ const { selection, collection } = context;
83
+ if (selection === null) {
84
+ return;
85
+ }
86
+ const planned = plannedPositions(context, selectedIds ?? []);
87
+ if (planned !== null) {
88
+ applySelection(selection, planned);
89
+ }
90
+ reportSelection(context, idsAt(collection, selectedPositions(selection)));
91
+ }
92
+ function observeSelection(context, selectedIds, onDrift) {
93
+ const { selection, collection } = context;
94
+ if (selection === null) {
72
95
  return;
73
96
  }
74
- applySelection(selection, collection, selectedIds);
97
+ const positions = selectedPositions(selection);
98
+ reportSelection(context, idsAt(collection, positions));
99
+ if (!isCollectionIdle(collection)) {
100
+ return;
101
+ }
102
+ const planned = plannedPositions(context, selectedIds ?? []);
103
+ if (planned !== null && hasSelectionDrifted(positions, planned)) {
104
+ onDrift();
105
+ }
75
106
  }
76
107
  function newLastSelection() {
77
108
  return { selection: null, key: null };
@@ -80,18 +111,20 @@ function useSelection(options) {
80
111
  const { collection, selectedIds, onSelectionChanged, selectionMode } = options;
81
112
  const [selection, setSelection] = useState(null);
82
113
  const [last] = useState(newLastSelection);
83
- const report = useEffectEvent(() => {
84
- reportSelection(selection, collection, last, onSelectionChanged);
114
+ const context = { selection, collection, last, onSelectionChanged };
115
+ const markDrift = useControlledSync({
116
+ ids: selectedIds,
117
+ collection,
118
+ widget: selection,
119
+ apply: (ids) => {
120
+ applyControlledSelection(context, ids);
121
+ },
85
122
  });
86
- useLayoutEffect(() => {
87
- syncSelection(selection, collection, selectedIds);
88
- report();
89
- }, [selection, collection, selectedIds]);
90
123
  return selectionElement(selectionMode, {
91
124
  ref: setSelection,
92
125
  model: collection.model,
93
126
  onSelectionChanged: () => {
94
- reportSelection(selection, collection, last, onSelectionChanged);
127
+ observeSelection(context, selectedIds, markDrift);
95
128
  },
96
129
  onItemsChanged: options.onItemsChanged,
97
130
  });
@@ -1 +1 @@
1
- {"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/internal/selection.tsx"],"names":[],"mappings":"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","sourcesContent":["import type * as Gio from \"@gtkx/gi/gio\";\nimport type { ReactElement } from \"react\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { GtkMultiSelection, GtkNoSelection, GtkSingleSelection } from \"@gtkx/jsx/gtk\";\nimport { useEffectEvent, useLayoutEffect, useState } from \"react\";\nimport type { Collection } from \"./collection.js\";\n\ntype SelectionOptions = {\n collection: Collection;\n selectedIds?: string[] | null | undefined;\n onSelectionChanged?: ((ids: string[]) => void) | null | undefined;\n selectionMode?: Gtk.SelectionMode | null | undefined;\n onItemsChanged: () => void;\n};\n\ntype LastSelection = {\n selection: Gtk.SelectionModel | null;\n key: string | null;\n};\n\ntype SelectionElementProps = {\n ref: (value: Gtk.SelectionModel | null) => void;\n model: Gio.ListModel;\n onSelectionChanged: () => void;\n onItemsChanged: () => void;\n};\n\nfunction getSelectedIds(selection: Gtk.SelectionModel, collection: Collection): string[] {\n const bitset = selection.getSelection();\n const size = Number(bitset.getSize());\n const ids: string[] = [];\n\n for (let index = 0; index < size; index++) {\n pushId(collection.idAt(bitset.getNth(index)), ids);\n }\n\n return ids;\n}\n\nfunction pushId(id: string | null, ids: string[]): void {\n if (id !== null) {\n ids.push(id);\n }\n}\n\nfunction applySingleSelection(selection: Gtk.SingleSelection, positions: number[]): void {\n const [first] = positions;\n\n if (first === undefined) {\n selection.unselectAll();\n\n return;\n }\n\n selection.selectItem(first, true);\n}\n\nfunction applyMultiSelection(selection: Gtk.SelectionModel, positions: number[]): void {\n const selected = Gtk.Bitset.newEmpty();\n\n for (const position of positions) {\n selected.add(position);\n }\n\n selection.setSelection(selected, Gtk.Bitset.newRange(0, selection.getNItems()));\n}\n\nfunction applySelection(selection: Gtk.SelectionModel, collection: Collection, ids: string[]): void {\n if (selection instanceof Gtk.NoSelection) {\n return;\n }\n\n const positions = collection.positionsFor(ids);\n\n if (ids.length > 0 && positions.length === 0) {\n return;\n }\n\n if (selection instanceof Gtk.SingleSelection) {\n applySingleSelection(selection, positions);\n\n return;\n }\n\n applyMultiSelection(selection, positions);\n}\n\nfunction reportSelection(\n selection: Gtk.SelectionModel | null,\n collection: Collection,\n last: LastSelection,\n onSelectionChanged: ((ids: string[]) => void) | null | undefined,\n): void {\n if (selection === null) {\n return;\n }\n\n const ids = getSelectedIds(selection, collection);\n const key = ids.join(\" \");\n\n if (last.selection === selection && last.key === key) {\n return;\n }\n\n last.selection = selection;\n last.key = key;\n onSelectionChanged?.(ids);\n}\n\nfunction selectionElement(mode: Gtk.SelectionMode | null | undefined, props: SelectionElementProps): ReactElement {\n if (mode === Gtk.SelectionMode.MULTIPLE) {\n return <GtkMultiSelection {...props} />;\n }\n\n if (mode === Gtk.SelectionMode.NONE) {\n return <GtkNoSelection {...props} />;\n }\n\n return <GtkSingleSelection {...props} autoselect={false} canUnselect />;\n}\n\nfunction syncSelection(\n selection: Gtk.SelectionModel | null,\n collection: Collection,\n selectedIds: string[] | null | undefined,\n): void {\n if (selection === null || selectedIds == null) {\n return;\n }\n\n applySelection(selection, collection, selectedIds);\n}\n\nfunction newLastSelection(): LastSelection {\n return { selection: null, key: null };\n}\n\nfunction useSelection(options: SelectionOptions): ReactElement {\n const { collection, selectedIds, onSelectionChanged, selectionMode } = options;\n const [selection, setSelection] = useState<Gtk.SelectionModel | null>(null);\n const [last] = useState<LastSelection>(newLastSelection);\n\n const report = useEffectEvent((): void => {\n reportSelection(selection, collection, last, onSelectionChanged);\n });\n\n useLayoutEffect(() => {\n syncSelection(selection, collection, selectedIds);\n report();\n }, [selection, collection, selectedIds]);\n\n return selectionElement(selectionMode, {\n ref: setSelection,\n model: collection.model,\n onSelectionChanged: () => {\n reportSelection(selection, collection, last, onSelectionChanged);\n },\n onItemsChanged: options.onItemsChanged,\n });\n}\n\nexport { useSelection, type SelectionOptions };\n"]}
1
+ {"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/internal/selection.tsx"],"names":[],"mappings":"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","sourcesContent":["import type * as Gio from \"@gtkx/gi/gio\";\nimport type { ReactElement } from \"react\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { GtkMultiSelection, GtkNoSelection, GtkSingleSelection } from \"@gtkx/jsx/gtk\";\nimport { useState } from \"react\";\nimport type { Collection } from \"./collection.js\";\nimport type { ItemsChangeHandler } from \"./expansion.js\";\nimport { isCollectionIdle } from \"./collection.js\";\nimport { useControlledSync } from \"./controlled-sync.js\";\nimport { joinParts } from \"./keys.js\";\n\ntype SelectionOptions = {\n collection: Collection;\n selectedIds?: string[] | null | undefined;\n onSelectionChanged?: ((ids: string[]) => void) | null | undefined;\n selectionMode?: Gtk.SelectionMode | null | undefined;\n onItemsChanged: ItemsChangeHandler;\n};\n\ntype LastSelection = {\n selection: Gtk.SelectionModel | null;\n key: string | null;\n};\n\ntype SelectionContext = {\n selection: Gtk.SelectionModel | null;\n collection: Collection;\n last: LastSelection;\n onSelectionChanged?: ((ids: string[]) => void) | null | undefined;\n};\n\ntype SelectionElementProps = {\n ref: (value: Gtk.SelectionModel | null) => void;\n model: Gio.ListModel;\n onSelectionChanged: () => void;\n onItemsChanged: ItemsChangeHandler;\n};\n\nfunction selectedPositions(selection: Gtk.SelectionModel): number[] {\n const bitset = selection.getSelection();\n const size = Number(bitset.getSize());\n const positions: number[] = [];\n\n for (let index = 0; index < size; index++) {\n positions.push(bitset.getNth(index));\n }\n\n return positions;\n}\n\nfunction idsAt(collection: Collection, positions: number[]): string[] {\n const ids: string[] = [];\n\n for (const position of positions) {\n const id = collection.idAt(position);\n\n if (id !== null) {\n ids.push(id);\n }\n }\n\n return ids;\n}\n\nfunction plannedPositions(context: SelectionContext, ids: string[]): number[] | null {\n const { selection, collection } = context;\n\n if (selection === null || selection instanceof Gtk.NoSelection) {\n return null;\n }\n\n const positions = collection.positionsFor(ids);\n\n if (ids.length > 0 && positions.length === 0) {\n return null;\n }\n\n return selection instanceof Gtk.SingleSelection ? positions.slice(0, 1) : positions;\n}\n\nfunction applySingleSelection(selection: Gtk.SingleSelection, positions: number[]): void {\n const [first] = positions;\n\n if (first === undefined) {\n selection.unselectAll();\n\n return;\n }\n\n selection.selectItem(first, true);\n}\n\nfunction applyMultiSelection(selection: Gtk.SelectionModel, positions: number[]): void {\n const selected = Gtk.Bitset.newEmpty();\n\n for (const position of positions) {\n selected.add(position);\n }\n\n selection.setSelection(selected, Gtk.Bitset.newRange(0, selection.getNItems()));\n}\n\nfunction applySelection(selection: Gtk.SelectionModel, positions: number[]): void {\n if (selection instanceof Gtk.SingleSelection) {\n applySingleSelection(selection, positions);\n\n return;\n }\n\n applyMultiSelection(selection, positions);\n}\n\nfunction reportSelection(context: SelectionContext, ids: string[]): void {\n const key = joinParts(ids);\n\n if (context.last.selection === context.selection && context.last.key === key) {\n return;\n }\n\n context.last.selection = context.selection;\n context.last.key = key;\n context.onSelectionChanged?.(ids);\n}\n\nfunction hasSelectionDrifted(actual: number[], planned: number[]): boolean {\n return actual.length !== planned.length || planned.some((position, index) => actual[index] !== position);\n}\n\nfunction selectionElement(mode: Gtk.SelectionMode | null | undefined, props: SelectionElementProps): ReactElement {\n if (mode === Gtk.SelectionMode.MULTIPLE) {\n return <GtkMultiSelection {...props} />;\n }\n\n if (mode === Gtk.SelectionMode.NONE) {\n return <GtkNoSelection {...props} />;\n }\n\n return <GtkSingleSelection {...props} autoselect={false} canUnselect />;\n}\n\nfunction applyControlledSelection(context: SelectionContext, selectedIds: string[] | null | undefined): void {\n const { selection, collection } = context;\n\n if (selection === null) {\n return;\n }\n\n const planned = plannedPositions(context, selectedIds ?? []);\n\n if (planned !== null) {\n applySelection(selection, planned);\n }\n\n reportSelection(context, idsAt(collection, selectedPositions(selection)));\n}\n\nfunction observeSelection(\n context: SelectionContext,\n selectedIds: string[] | null | undefined,\n onDrift: () => void,\n): void {\n const { selection, collection } = context;\n\n if (selection === null) {\n return;\n }\n\n const positions = selectedPositions(selection);\n reportSelection(context, idsAt(collection, positions));\n\n if (!isCollectionIdle(collection)) {\n return;\n }\n\n const planned = plannedPositions(context, selectedIds ?? []);\n\n if (planned !== null && hasSelectionDrifted(positions, planned)) {\n onDrift();\n }\n}\n\nfunction newLastSelection(): LastSelection {\n return { selection: null, key: null };\n}\n\nfunction useSelection(options: SelectionOptions): ReactElement {\n const { collection, selectedIds, onSelectionChanged, selectionMode } = options;\n const [selection, setSelection] = useState<Gtk.SelectionModel | null>(null);\n const [last] = useState<LastSelection>(newLastSelection);\n const context: SelectionContext = { selection, collection, last, onSelectionChanged };\n\n const markDrift = useControlledSync({\n ids: selectedIds,\n collection,\n widget: selection,\n apply: (ids) => {\n applyControlledSelection(context, ids);\n },\n });\n\n return selectionElement(selectionMode, {\n ref: setSelection,\n model: collection.model,\n onSelectionChanged: () => {\n observeSelection(context, selectedIds, markDrift);\n },\n onItemsChanged: options.onItemsChanged,\n });\n}\n\nexport { useSelection };\n"]}
@@ -0,0 +1,10 @@
1
+ type SlotKey = {
2
+ levelPath: string;
3
+ slot: number;
4
+ };
5
+ type SlotMap = Map<string, Set<number>>;
6
+ declare function getSlotKey(path: string): SlotKey | null;
7
+ declare function trackPath(slots: SlotMap, path: string): void;
8
+ declare function trackPaths(paths: Iterable<string>): SlotMap;
9
+ export { getSlotKey, trackPath, trackPaths, type SlotMap };
10
+ //# sourceMappingURL=slots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../src/internal/slots.ts"],"names":[],"mappings":"AAEA,KAAK,OAAO,GAAG;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAoBxC,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAShD;AAED,iBAAS,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAgBrD;AAED,iBAAS,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAQpD;AAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,OAAO,EAAE,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { decodePartAt, encodePart } from "./keys.js";
2
+ function getLevelBoundary(path) {
3
+ let offset = 0;
4
+ let boundary = 0;
5
+ while (offset < path.length) {
6
+ const part = decodePartAt(path, offset);
7
+ if (part === null) {
8
+ return boundary;
9
+ }
10
+ boundary = offset;
11
+ offset += encodePart(part).length;
12
+ }
13
+ return boundary;
14
+ }
15
+ function getSlotKey(path) {
16
+ const boundary = getLevelBoundary(path);
17
+ const part = decodePartAt(path, boundary);
18
+ if (part === null) {
19
+ return null;
20
+ }
21
+ return { levelPath: path.slice(0, boundary), slot: Number(part) };
22
+ }
23
+ function trackPath(slots, path) {
24
+ const key = getSlotKey(path);
25
+ if (key === null) {
26
+ return;
27
+ }
28
+ const level = slots.get(key.levelPath);
29
+ if (level === undefined) {
30
+ slots.set(key.levelPath, new Set([key.slot]));
31
+ return;
32
+ }
33
+ level.add(key.slot);
34
+ }
35
+ function trackPaths(paths) {
36
+ const slots = new Map();
37
+ for (const path of paths) {
38
+ trackPath(slots, path);
39
+ }
40
+ return slots;
41
+ }
42
+ export { getSlotKey, trackPath, trackPaths };
43
+ //# sourceMappingURL=slots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.js","sourceRoot":"","sources":["../../src/internal/slots.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AASrD,SAAS,gBAAgB,CAAC,IAAY;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAExC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,QAAQ,GAAG,MAAM,CAAC;QAClB,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC5B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE1C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,SAAS,CAAC,KAAc,EAAE,IAAY;IAC3C,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAE7B,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACf,OAAO;IACX,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE9C,OAAO;IACX,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB;IACvC,MAAM,KAAK,GAAY,IAAI,GAAG,EAAE,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAgB,CAAC","sourcesContent":["import { decodePartAt, encodePart } from \"./keys.js\";\n\ntype SlotKey = {\n levelPath: string;\n slot: number;\n};\n\ntype SlotMap = Map<string, Set<number>>;\n\nfunction getLevelBoundary(path: string): number {\n let offset = 0;\n let boundary = 0;\n\n while (offset < path.length) {\n const part = decodePartAt(path, offset);\n\n if (part === null) {\n return boundary;\n }\n\n boundary = offset;\n offset += encodePart(part).length;\n }\n\n return boundary;\n}\n\nfunction getSlotKey(path: string): SlotKey | null {\n const boundary = getLevelBoundary(path);\n const part = decodePartAt(path, boundary);\n\n if (part === null) {\n return null;\n }\n\n return { levelPath: path.slice(0, boundary), slot: Number(part) };\n}\n\nfunction trackPath(slots: SlotMap, path: string): void {\n const key = getSlotKey(path);\n\n if (key === null) {\n return;\n }\n\n const level = slots.get(key.levelPath);\n\n if (level === undefined) {\n slots.set(key.levelPath, new Set([key.slot]));\n\n return;\n }\n\n level.add(key.slot);\n}\n\nfunction trackPaths(paths: Iterable<string>): SlotMap {\n const slots: SlotMap = new Map();\n\n for (const path of paths) {\n trackPath(slots, path);\n }\n\n return slots;\n}\n\nexport { getSlotKey, trackPath, trackPaths, type SlotMap };\n"]}
@@ -0,0 +1,19 @@
1
+ import type { CollectionIndex } from "./collection-index.js";
2
+ import type { SlotMap } from "./slots.js";
3
+ import type { VisibleOrder } from "./tree-order.js";
4
+ type TreeExpansion = {
5
+ index: CollectionIndex;
6
+ expanded: Set<string>;
7
+ slots: SlotMap;
8
+ order: VisibleOrder | null;
9
+ isApplying: boolean;
10
+ isSyncing: boolean;
11
+ };
12
+ declare function createTreeExpansion(index: CollectionIndex): TreeExpansion;
13
+ declare function orderFor(expansion: TreeExpansion): VisibleOrder;
14
+ declare function adoptOrder(expansion: TreeExpansion, order: VisibleOrder): void;
15
+ declare function pruneSlots(expansion: TreeExpansion, levelPath: string, isPruned: (slot: number) => boolean): void;
16
+ declare function markExpanded(expansion: TreeExpansion, path: string, isExpanded: boolean): void;
17
+ declare function adoptIndex(expansion: TreeExpansion, index: CollectionIndex): void;
18
+ export { adoptIndex, adoptOrder, createTreeExpansion, markExpanded, orderFor, pruneSlots, type TreeExpansion, };
19
+ //# sourceMappingURL=tree-expansion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-expansion.d.ts","sourceRoot":"","sources":["../../src/internal/tree-expansion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAKpD,KAAK,aAAa,GAAG;IACjB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AA6BF,iBAAS,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,CAElE;AAED,iBAAS,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,YAAY,CAIxD;AAED,iBAAS,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAIvE;AAaD,iBAAS,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAiB1G;AAED,iBAAS,YAAY,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,CAUvF;AAED,iBAAS,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAG1E;AAED,OAAO,EACH,UAAU,EACV,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,KAAK,aAAa,GACrB,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { encodePart } from "./keys.js";
2
+ import { getSlotKey, trackPath, trackPaths } from "./slots.js";
3
+ import { buildVisibleOrder } from "./tree-order.js";
4
+ function dropLevel(expansion, path, pending) {
5
+ expansion.expanded.delete(path);
6
+ const level = expansion.slots.get(path);
7
+ if (level === undefined) {
8
+ return;
9
+ }
10
+ expansion.slots.delete(path);
11
+ for (const slot of level) {
12
+ pending.push(path + encodePart(String(slot)));
13
+ }
14
+ }
15
+ function dropSubtree(expansion, path) {
16
+ const pending = [path];
17
+ while (pending.length > 0) {
18
+ const current = pending.pop();
19
+ if (current !== undefined) {
20
+ dropLevel(expansion, current, pending);
21
+ }
22
+ }
23
+ }
24
+ function createTreeExpansion(index) {
25
+ return { index, expanded: new Set(), slots: new Map(), order: null, isApplying: false, isSyncing: false };
26
+ }
27
+ function orderFor(expansion) {
28
+ expansion.order ??= buildVisibleOrder(expansion.index, expansion.slots);
29
+ return expansion.order;
30
+ }
31
+ function adoptOrder(expansion, order) {
32
+ expansion.expanded = new Set(order.expandedPaths);
33
+ expansion.slots = trackPaths(order.expandedPaths);
34
+ expansion.order = order;
35
+ }
36
+ function prunePath(expansion, path) {
37
+ const key = getSlotKey(path);
38
+ if (key !== null) {
39
+ expansion.slots.get(key.levelPath)?.delete(key.slot);
40
+ }
41
+ dropSubtree(expansion, path);
42
+ expansion.order = null;
43
+ }
44
+ function pruneSlots(expansion, levelPath, isPruned) {
45
+ const level = expansion.slots.get(levelPath);
46
+ if (level === undefined) {
47
+ return;
48
+ }
49
+ for (const slot of level) {
50
+ if (!isPruned(slot)) {
51
+ continue;
52
+ }
53
+ level.delete(slot);
54
+ dropSubtree(expansion, levelPath + encodePart(String(slot)));
55
+ }
56
+ expansion.order = null;
57
+ }
58
+ function markExpanded(expansion, path, isExpanded) {
59
+ if (isExpanded) {
60
+ expansion.expanded.add(path);
61
+ trackPath(expansion.slots, path);
62
+ expansion.order = null;
63
+ return;
64
+ }
65
+ prunePath(expansion, path);
66
+ }
67
+ function adoptIndex(expansion, index) {
68
+ expansion.index = index;
69
+ expansion.order = null;
70
+ }
71
+ export { adoptIndex, adoptOrder, createTreeExpansion, markExpanded, orderFor, pruneSlots, };
72
+ //# sourceMappingURL=tree-expansion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-expansion.js","sourceRoot":"","sources":["../../src/internal/tree-expansion.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CollectionIndex } from \"./collection-index.js\";\nimport type { SlotMap } from \"./slots.js\";\nimport type { VisibleOrder } from \"./tree-order.js\";\nimport { encodePart } from \"./keys.js\";\nimport { getSlotKey, trackPath, trackPaths } from \"./slots.js\";\nimport { buildVisibleOrder } from \"./tree-order.js\";\n\ntype TreeExpansion = {\n index: CollectionIndex;\n expanded: Set<string>;\n slots: SlotMap;\n order: VisibleOrder | null;\n isApplying: boolean;\n isSyncing: boolean;\n};\n\nfunction dropLevel(expansion: TreeExpansion, path: string, pending: string[]): void {\n expansion.expanded.delete(path);\n const level = expansion.slots.get(path);\n\n if (level === undefined) {\n return;\n }\n\n expansion.slots.delete(path);\n\n for (const slot of level) {\n pending.push(path + encodePart(String(slot)));\n }\n}\n\nfunction dropSubtree(expansion: TreeExpansion, path: string): void {\n const pending: string[] = [path];\n\n while (pending.length > 0) {\n const current = pending.pop();\n\n if (current !== undefined) {\n dropLevel(expansion, current, pending);\n }\n }\n}\n\nfunction createTreeExpansion(index: CollectionIndex): TreeExpansion {\n return { index, expanded: new Set(), slots: new Map(), order: null, isApplying: false, isSyncing: false };\n}\n\nfunction orderFor(expansion: TreeExpansion): VisibleOrder {\n expansion.order ??= buildVisibleOrder(expansion.index, expansion.slots);\n\n return expansion.order;\n}\n\nfunction adoptOrder(expansion: TreeExpansion, order: VisibleOrder): void {\n expansion.expanded = new Set(order.expandedPaths);\n expansion.slots = trackPaths(order.expandedPaths);\n expansion.order = order;\n}\n\nfunction prunePath(expansion: TreeExpansion, path: string): void {\n const key = getSlotKey(path);\n\n if (key !== null) {\n expansion.slots.get(key.levelPath)?.delete(key.slot);\n }\n\n dropSubtree(expansion, path);\n expansion.order = null;\n}\n\nfunction pruneSlots(expansion: TreeExpansion, levelPath: string, isPruned: (slot: number) => boolean): void {\n const level = expansion.slots.get(levelPath);\n\n if (level === undefined) {\n return;\n }\n\n for (const slot of level) {\n if (!isPruned(slot)) {\n continue;\n }\n\n level.delete(slot);\n dropSubtree(expansion, levelPath + encodePart(String(slot)));\n }\n\n expansion.order = null;\n}\n\nfunction markExpanded(expansion: TreeExpansion, path: string, isExpanded: boolean): void {\n if (isExpanded) {\n expansion.expanded.add(path);\n trackPath(expansion.slots, path);\n expansion.order = null;\n\n return;\n }\n\n prunePath(expansion, path);\n}\n\nfunction adoptIndex(expansion: TreeExpansion, index: CollectionIndex): void {\n expansion.index = index;\n expansion.order = null;\n}\n\nexport {\n adoptIndex,\n adoptOrder,\n createTreeExpansion,\n markExpanded,\n orderFor,\n pruneSlots,\n type TreeExpansion,\n};\n"]}
@@ -0,0 +1,26 @@
1
+ import type { ListItem } from "../types.js";
2
+ import type { CollectionIndex } from "./collection-index.js";
3
+ import type { SlotMap } from "./slots.js";
4
+ type VisibleRow = {
5
+ item: ListItem;
6
+ position: number;
7
+ isOpen: boolean;
8
+ isMarked: boolean;
9
+ };
10
+ type VisibleOrder = {
11
+ expandedPaths: string[];
12
+ expandedIds: string[];
13
+ };
14
+ type RowVisitor = (row: VisibleRow) => void;
15
+ type WalkOptions = {
16
+ index: CollectionIndex;
17
+ slots: SlotMap;
18
+ marks?: SlotMap | undefined;
19
+ visit?: RowVisitor | undefined;
20
+ };
21
+ declare function walkVisible(options: WalkOptions): VisibleOrder;
22
+ declare function expandedPathsFor(index: CollectionIndex, ids: Set<string>): Set<string>;
23
+ declare function buildVisibleOrder(index: CollectionIndex, slots: SlotMap): VisibleOrder;
24
+ declare function findPositions(index: CollectionIndex, slots: SlotMap, ids: Set<string>): number[];
25
+ export { buildVisibleOrder, expandedPathsFor, findPositions, walkVisible, type VisibleOrder, type WalkOptions, };
26
+ //# sourceMappingURL=tree-order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-order.d.ts","sourceRoot":"","sources":["../../src/internal/tree-order.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAS,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,KAAK,UAAU,GAAG;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,KAAK,YAAY,GAAG;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;AAE5C,KAAK,WAAW,GAAG;IACf,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CAClC,CAAC;AA2FF,iBAAS,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,CAevD;AA0BD,iBAAS,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAuB/E;AAED,iBAAS,iBAAiB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,GAAG,YAAY,CAE/E;AAED,iBAAS,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAczF;AAED,OAAO,EACH,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,WAAW,GACnB,CAAC"}
@@ -0,0 +1,109 @@
1
+ const NO_ITEM = { id: "", value: undefined };
2
+ function advanceStack(stack, onSlot, onLeave) {
3
+ const frame = stack.at(-1);
4
+ if (frame === undefined) {
5
+ return;
6
+ }
7
+ if (frame.cursor >= frame.level.items.length) {
8
+ stack.pop();
9
+ onLeave?.(frame);
10
+ return;
11
+ }
12
+ const slot = frame.cursor;
13
+ frame.cursor += 1;
14
+ onSlot(frame, slot);
15
+ }
16
+ function frameFor(options, level) {
17
+ return { level, cursor: 0, open: options.slots.get(level.path), marked: options.marks?.get(level.path) };
18
+ }
19
+ function descend(state, level, slot) {
20
+ const child = state.options.index.childLevel(level, slot);
21
+ if (child === undefined) {
22
+ return;
23
+ }
24
+ state.order.expandedPaths.push(child.path);
25
+ state.order.expandedIds.push(state.row.item.id);
26
+ state.stack.push(frameFor(state.options, child));
27
+ }
28
+ function visitSlot(state, frame, slot) {
29
+ const item = frame.level.items[slot];
30
+ if (item === undefined) {
31
+ return;
32
+ }
33
+ const { row } = state;
34
+ row.item = item;
35
+ row.isOpen = frame.open?.has(slot) ?? false;
36
+ row.isMarked = frame.marked?.has(slot) ?? false;
37
+ state.options.visit?.(row);
38
+ row.position += 1;
39
+ if (row.isOpen) {
40
+ descend(state, frame.level, slot);
41
+ }
42
+ }
43
+ function walkVisible(options) {
44
+ const order = { expandedPaths: [], expandedIds: [] };
45
+ const row = { item: NO_ITEM, position: 0, isOpen: false, isMarked: false };
46
+ const frames = options.index.groups.map((level) => frameFor(options, level));
47
+ const state = { options, stack: frames.toReversed(), row, order };
48
+ const onSlot = (frame, slot) => {
49
+ visitSlot(state, frame, slot);
50
+ };
51
+ while (state.stack.length > 0) {
52
+ advanceStack(state.stack, onSlot);
53
+ }
54
+ return order;
55
+ }
56
+ function openSlot(walk, frame, slot) {
57
+ const item = frame.level.items[slot];
58
+ if (item === undefined || !walk.ids.has(item.id) || walk.ancestors.has(item)) {
59
+ return;
60
+ }
61
+ const child = walk.index.childLevel(frame.level, slot);
62
+ if (child === undefined) {
63
+ return;
64
+ }
65
+ walk.paths.add(child.path);
66
+ walk.ancestors.add(item);
67
+ walk.stack.push({ level: child, cursor: 0, owner: item });
68
+ }
69
+ function leaveOpenFrame(walk, frame) {
70
+ if (frame.owner !== null) {
71
+ walk.ancestors.delete(frame.owner);
72
+ }
73
+ }
74
+ function expandedPathsFor(index, ids) {
75
+ const paths = new Set();
76
+ if (ids.size === 0 || !index.isTree) {
77
+ return paths;
78
+ }
79
+ const frames = index.groups.map((level) => ({ level, cursor: 0, owner: null }));
80
+ const walk = { index, ids, paths, stack: frames.toReversed(), ancestors: new Set() };
81
+ const onSlot = (frame, slot) => {
82
+ openSlot(walk, frame, slot);
83
+ };
84
+ const onLeave = (frame) => {
85
+ leaveOpenFrame(walk, frame);
86
+ };
87
+ while (walk.stack.length > 0) {
88
+ advanceStack(walk.stack, onSlot, onLeave);
89
+ }
90
+ return paths;
91
+ }
92
+ function buildVisibleOrder(index, slots) {
93
+ return walkVisible({ index, slots });
94
+ }
95
+ function findPositions(index, slots, ids) {
96
+ const found = [];
97
+ walkVisible({
98
+ index,
99
+ slots,
100
+ visit: (row) => {
101
+ if (ids.has(row.item.id)) {
102
+ found.push(row.position);
103
+ }
104
+ },
105
+ });
106
+ return found;
107
+ }
108
+ export { buildVisibleOrder, expandedPathsFor, findPositions, walkVisible, };
109
+ //# sourceMappingURL=tree-order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-order.js","sourceRoot":"","sources":["../../src/internal/tree-order.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ListItem } from \"../types.js\";\nimport type { CollectionIndex, Level } from \"./collection-index.js\";\nimport type { SlotMap } from \"./slots.js\";\n\ntype VisibleRow = {\n item: ListItem;\n position: number;\n isOpen: boolean;\n isMarked: boolean;\n};\n\ntype VisibleOrder = {\n expandedPaths: string[];\n expandedIds: string[];\n};\n\ntype RowVisitor = (row: VisibleRow) => void;\n\ntype WalkOptions = {\n index: CollectionIndex;\n slots: SlotMap;\n marks?: SlotMap | undefined;\n visit?: RowVisitor | undefined;\n};\n\ntype LevelFrame = {\n level: Level;\n cursor: number;\n};\n\ntype WalkFrame = LevelFrame & {\n open: Set<number> | undefined;\n marked: Set<number> | undefined;\n};\n\ntype WalkState = {\n options: WalkOptions;\n stack: WalkFrame[];\n row: VisibleRow;\n order: VisibleOrder;\n};\n\ntype OpenFrame = LevelFrame & {\n owner: ListItem | null;\n};\n\ntype OpenWalk = {\n index: CollectionIndex;\n ids: Set<string>;\n paths: Set<string>;\n stack: OpenFrame[];\n ancestors: Set<ListItem>;\n};\n\nconst NO_ITEM: ListItem = { id: \"\", value: undefined };\n\nfunction advanceStack<F extends LevelFrame>(\n stack: F[],\n onSlot: (frame: F, slot: number) => void,\n onLeave?: (frame: F) => void,\n): void {\n const frame = stack.at(-1);\n\n if (frame === undefined) {\n return;\n }\n\n if (frame.cursor >= frame.level.items.length) {\n stack.pop();\n onLeave?.(frame);\n\n return;\n }\n\n const slot = frame.cursor;\n frame.cursor += 1;\n onSlot(frame, slot);\n}\n\nfunction frameFor(options: WalkOptions, level: Level): WalkFrame {\n return { level, cursor: 0, open: options.slots.get(level.path), marked: options.marks?.get(level.path) };\n}\n\nfunction descend(state: WalkState, level: Level, slot: number): void {\n const child = state.options.index.childLevel(level, slot);\n\n if (child === undefined) {\n return;\n }\n\n state.order.expandedPaths.push(child.path);\n state.order.expandedIds.push(state.row.item.id);\n state.stack.push(frameFor(state.options, child));\n}\n\nfunction visitSlot(state: WalkState, frame: WalkFrame, slot: number): void {\n const item = frame.level.items[slot];\n\n if (item === undefined) {\n return;\n }\n\n const { row } = state;\n row.item = item;\n row.isOpen = frame.open?.has(slot) ?? false;\n row.isMarked = frame.marked?.has(slot) ?? false;\n state.options.visit?.(row);\n row.position += 1;\n\n if (row.isOpen) {\n descend(state, frame.level, slot);\n }\n}\n\nfunction walkVisible(options: WalkOptions): VisibleOrder {\n const order: VisibleOrder = { expandedPaths: [], expandedIds: [] };\n const row: VisibleRow = { item: NO_ITEM, position: 0, isOpen: false, isMarked: false };\n const frames = options.index.groups.map((level) => frameFor(options, level));\n const state: WalkState = { options, stack: frames.toReversed(), row, order };\n\n const onSlot = (frame: WalkFrame, slot: number): void => {\n visitSlot(state, frame, slot);\n };\n\n while (state.stack.length > 0) {\n advanceStack(state.stack, onSlot);\n }\n\n return order;\n}\n\nfunction openSlot(walk: OpenWalk, frame: OpenFrame, slot: number): void {\n const item = frame.level.items[slot];\n\n if (item === undefined || !walk.ids.has(item.id) || walk.ancestors.has(item)) {\n return;\n }\n\n const child = walk.index.childLevel(frame.level, slot);\n\n if (child === undefined) {\n return;\n }\n\n walk.paths.add(child.path);\n walk.ancestors.add(item);\n walk.stack.push({ level: child, cursor: 0, owner: item });\n}\n\nfunction leaveOpenFrame(walk: OpenWalk, frame: OpenFrame): void {\n if (frame.owner !== null) {\n walk.ancestors.delete(frame.owner);\n }\n}\n\nfunction expandedPathsFor(index: CollectionIndex, ids: Set<string>): Set<string> {\n const paths: Set<string> = new Set();\n\n if (ids.size === 0 || !index.isTree) {\n return paths;\n }\n\n const frames = index.groups.map((level) => ({ level, cursor: 0, owner: null }));\n const walk: OpenWalk = { index, ids, paths, stack: frames.toReversed(), ancestors: new Set() };\n\n const onSlot = (frame: OpenFrame, slot: number): void => {\n openSlot(walk, frame, slot);\n };\n\n const onLeave = (frame: OpenFrame): void => {\n leaveOpenFrame(walk, frame);\n };\n\n while (walk.stack.length > 0) {\n advanceStack(walk.stack, onSlot, onLeave);\n }\n\n return paths;\n}\n\nfunction buildVisibleOrder(index: CollectionIndex, slots: SlotMap): VisibleOrder {\n return walkVisible({ index, slots });\n}\n\nfunction findPositions(index: CollectionIndex, slots: SlotMap, ids: Set<string>): number[] {\n const found: number[] = [];\n\n walkVisible({\n index,\n slots,\n visit: (row) => {\n if (ids.has(row.item.id)) {\n found.push(row.position);\n }\n },\n });\n\n return found;\n}\n\nexport {\n buildVisibleOrder,\n expandedPathsFor,\n findPositions,\n walkVisible,\n type VisibleOrder,\n type WalkOptions,\n};\n"]}
@@ -13,5 +13,5 @@ type CollectionResult = {
13
13
  };
14
14
  declare function useCollectionData(options: CollectionDataOptions): Collection;
15
15
  declare function useCollection(options: CollectionOptions): CollectionResult;
16
- export { useCollection, useCollectionData, type CollectionDataOptions, type CollectionOptions };
16
+ export { useCollection, useCollectionData };
17
17
  //# sourceMappingURL=use-collection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-collection.d.ts","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlD,KAAK,qBAAqB,GAAG;IACzB,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,KAAK,iBAAiB,GAAG,qBAAqB,GAAG,cAAc,GAAG,cAAc,CAAC;AAEjF,KAAK,gBAAgB,GAAG;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,iBAAS,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAWrE;AAED,iBAAS,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAkBnE;AAED,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"use-collection.d.ts","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlD,KAAK,qBAAqB,GAAG;IACzB,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,KAAK,iBAAiB,GAAG,qBAAqB,GAAG,cAAc,GAAG,cAAc,CAAC;AAEjF,KAAK,gBAAgB,GAAG;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,iBAAS,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAWrE;AAED,iBAAS,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAkBnE;AAED,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC"}
@@ -6,12 +6,12 @@ import { useExpansion } from "./expansion.js";
6
6
  import { useSelection } from "./selection.js";
7
7
  function useCollectionData(options) {
8
8
  const { items, sections, isFlat } = options;
9
- const [gtk] = useState(createCollectionModel);
9
+ const [collectionModel] = useState(createCollectionModel);
10
10
  const index = useMemo(() => createCollectionIndex(items, sections, isFlat === true), [items, sections, isFlat]);
11
- const collection = useMemo(() => createCollection(gtk, index), [gtk, index]);
11
+ const collection = useMemo(() => createCollection(collectionModel, index), [collectionModel, index]);
12
12
  useLayoutEffect(() => {
13
- gtk.sync(index);
14
- }, [gtk, index]);
13
+ collectionModel.sync(index);
14
+ }, [collectionModel, index]);
15
15
  return collection;
16
16
  }
17
17
  function useCollection(options) {
@@ -1 +1 @@
1
- {"version":3,"file":"use-collection.js","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAe9C,SAAS,iBAAiB,CAAC,OAA8B;IACrD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAChH,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAE7E,eAAe,CAAC,GAAG,EAAE;QACjB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAEjB,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,SAAS,aAAa,CAAC,OAA0B;IAC7C,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE9C,MAAM,cAAc,GAAG,YAAY,CAAC;QAChC,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;KAC7C,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,YAAY,CAAC;QAC3B,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,cAAc;KACjB,CAAC,CAAC;IAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAsD,CAAC","sourcesContent":["import type { ReactElement } from \"react\";\nimport { useLayoutEffect, useMemo, useState } from \"react\";\nimport type { ExpansionProps, ListItem, ListSection, SelectionProps } from \"../types.js\";\nimport type { Collection } from \"./collection.js\";\nimport { createCollectionIndex } from \"./collection-index.js\";\nimport { createCollectionModel } from \"./collection-model.js\";\nimport { createCollection } from \"./collection.js\";\nimport { useExpansion } from \"./expansion.js\";\nimport { useSelection } from \"./selection.js\";\n\ntype CollectionDataOptions = {\n items?: ListItem[] | undefined;\n sections?: ListSection[] | undefined;\n isFlat?: boolean | undefined;\n};\n\ntype CollectionOptions = CollectionDataOptions & SelectionProps & ExpansionProps;\n\ntype CollectionResult = {\n collection: Collection;\n selection: ReactElement;\n};\n\nfunction useCollectionData(options: CollectionDataOptions): Collection {\n const { items, sections, isFlat } = options;\n const [gtk] = useState(createCollectionModel);\n const index = useMemo(() => createCollectionIndex(items, sections, isFlat === true), [items, sections, isFlat]);\n const collection = useMemo(() => createCollection(gtk, index), [gtk, index]);\n\n useLayoutEffect(() => {\n gtk.sync(index);\n }, [gtk, index]);\n\n return collection;\n}\n\nfunction useCollection(options: CollectionOptions): CollectionResult {\n const collection = useCollectionData(options);\n\n const onItemsChanged = useExpansion({\n collection,\n expandedIds: options.expandedIds,\n onExpandedChange: options.onExpandedChange,\n });\n\n const selection = useSelection({\n collection,\n selectedIds: options.selectedIds,\n onSelectionChanged: options.onSelectionChanged,\n selectionMode: options.selectionMode,\n onItemsChanged,\n });\n\n return { collection, selection };\n}\n\nexport { useCollection, useCollectionData, type CollectionDataOptions, type CollectionOptions };\n"]}
1
+ {"version":3,"file":"use-collection.js","sourceRoot":"","sources":["../../src/internal/use-collection.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAe9C,SAAS,iBAAiB,CAAC,OAA8B;IACrD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAChH,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;IAErG,eAAe,CAAC,GAAG,EAAE;QACjB,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;IAE7B,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,SAAS,aAAa,CAAC,OAA0B;IAC7C,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE9C,MAAM,cAAc,GAAG,YAAY,CAAC;QAChC,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;KAC7C,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,YAAY,CAAC;QAC3B,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,cAAc;KACjB,CAAC,CAAC;IAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import type { ReactElement } from \"react\";\nimport { useLayoutEffect, useMemo, useState } from \"react\";\nimport type { ExpansionProps, ListItem, ListSection, SelectionProps } from \"../types.js\";\nimport type { Collection } from \"./collection.js\";\nimport { createCollectionIndex } from \"./collection-index.js\";\nimport { createCollectionModel } from \"./collection-model.js\";\nimport { createCollection } from \"./collection.js\";\nimport { useExpansion } from \"./expansion.js\";\nimport { useSelection } from \"./selection.js\";\n\ntype CollectionDataOptions = {\n items?: ListItem[] | undefined;\n sections?: ListSection[] | undefined;\n isFlat?: boolean | undefined;\n};\n\ntype CollectionOptions = CollectionDataOptions & SelectionProps & ExpansionProps;\n\ntype CollectionResult = {\n collection: Collection;\n selection: ReactElement;\n};\n\nfunction useCollectionData(options: CollectionDataOptions): Collection {\n const { items, sections, isFlat } = options;\n const [collectionModel] = useState(createCollectionModel);\n const index = useMemo(() => createCollectionIndex(items, sections, isFlat === true), [items, sections, isFlat]);\n const collection = useMemo(() => createCollection(collectionModel, index), [collectionModel, index]);\n\n useLayoutEffect(() => {\n collectionModel.sync(index);\n }, [collectionModel, index]);\n\n return collection;\n}\n\nfunction useCollection(options: CollectionOptions): CollectionResult {\n const collection = useCollectionData(options);\n\n const onItemsChanged = useExpansion({\n collection,\n expandedIds: options.expandedIds,\n onExpandedChange: options.onExpandedChange,\n });\n\n const selection = useSelection({\n collection,\n selectedIds: options.selectedIds,\n onSelectionChanged: options.onSelectionChanged,\n selectionMode: options.selectionMode,\n onItemsChanged,\n });\n\n return { collection, selection };\n}\n\nexport { useCollection, useCollectionData };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"list-view.d.ts","sourceRoot":"","sources":["../src/list-view.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkBhD;;;GAGG;AACH,iBAAS,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAwBjF;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"list-view.d.ts","sourceRoot":"","sources":["../src/list-view.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAmBhD;;;GAGG;AACH,iBAAS,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CA2BjF;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}