@gtkx/components 2.0.0-beta.11 → 2.0.0-beta.13

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 (92) hide show
  1. package/README.md +4 -4
  2. package/dist/column-view.d.ts.map +1 -1
  3. package/dist/column-view.js +8 -4
  4. package/dist/column-view.js.map +1 -1
  5. package/dist/combo-row.d.ts.map +1 -1
  6. package/dist/combo-row.js +3 -1
  7. package/dist/combo-row.js.map +1 -1
  8. package/dist/grid-view.d.ts.map +1 -1
  9. package/dist/grid-view.js +4 -3
  10. package/dist/grid-view.js.map +1 -1
  11. package/dist/internal/cells.d.ts +8 -9
  12. package/dist/internal/cells.d.ts.map +1 -1
  13. package/dist/internal/cells.js +98 -83
  14. package/dist/internal/cells.js.map +1 -1
  15. package/dist/internal/collection-index.d.ts +3 -5
  16. package/dist/internal/collection-index.d.ts.map +1 -1
  17. package/dist/internal/collection-index.js +3 -7
  18. package/dist/internal/collection-index.js.map +1 -1
  19. package/dist/internal/collection-model.d.ts +15 -4
  20. package/dist/internal/collection-model.d.ts.map +1 -1
  21. package/dist/internal/collection-model.js +154 -73
  22. package/dist/internal/collection-model.js.map +1 -1
  23. package/dist/internal/collection.d.ts +3 -3
  24. package/dist/internal/collection.d.ts.map +1 -1
  25. package/dist/internal/collection.js +11 -9
  26. package/dist/internal/collection.js.map +1 -1
  27. package/dist/internal/controlled-sync.d.ts +2 -1
  28. package/dist/internal/controlled-sync.d.ts.map +1 -1
  29. package/dist/internal/controlled-sync.js +6 -1
  30. package/dist/internal/controlled-sync.js.map +1 -1
  31. package/dist/internal/drop-down.d.ts +10 -4
  32. package/dist/internal/drop-down.d.ts.map +1 -1
  33. package/dist/internal/drop-down.js +61 -9
  34. package/dist/internal/drop-down.js.map +1 -1
  35. package/dist/internal/expansion.d.ts.map +1 -1
  36. package/dist/internal/expansion.js +46 -19
  37. package/dist/internal/expansion.js.map +1 -1
  38. package/dist/internal/first-header.d.ts +11 -0
  39. package/dist/internal/first-header.d.ts.map +1 -0
  40. package/dist/internal/first-header.js +21 -0
  41. package/dist/internal/first-header.js.map +1 -0
  42. package/dist/internal/keys.d.ts.map +1 -1
  43. package/dist/internal/level-splice.d.ts +27 -0
  44. package/dist/internal/level-splice.d.ts.map +1 -0
  45. package/dist/internal/level-splice.js +98 -0
  46. package/dist/internal/level-splice.js.map +1 -0
  47. package/dist/internal/selection.d.ts.map +1 -1
  48. package/dist/internal/selection.js +23 -16
  49. package/dist/internal/selection.js.map +1 -1
  50. package/dist/internal/tree-expansion.d.ts +3 -1
  51. package/dist/internal/tree-expansion.d.ts.map +1 -1
  52. package/dist/internal/tree-expansion.js +31 -2
  53. package/dist/internal/tree-expansion.js.map +1 -1
  54. package/dist/internal/tree-order.d.ts +2 -1
  55. package/dist/internal/tree-order.d.ts.map +1 -1
  56. package/dist/internal/tree-order.js +3 -2
  57. package/dist/internal/tree-order.js.map +1 -1
  58. package/dist/internal/use-collection.d.ts +1 -0
  59. package/dist/internal/use-collection.d.ts.map +1 -1
  60. package/dist/internal/use-collection.js +6 -2
  61. package/dist/internal/use-collection.js.map +1 -1
  62. package/dist/internal/use-widget-ref.d.ts.map +1 -1
  63. package/dist/list-item-factory.d.ts +1 -1
  64. package/dist/list-item-factory.d.ts.map +1 -1
  65. package/dist/list-item-factory.js +3 -3
  66. package/dist/list-item-factory.js.map +1 -1
  67. package/dist/list-view.d.ts.map +1 -1
  68. package/dist/list-view.js +9 -4
  69. package/dist/list-view.js.map +1 -1
  70. package/dist/types.d.ts +35 -12
  71. package/dist/types.d.ts.map +1 -1
  72. package/dist/types.js.map +1 -1
  73. package/package.json +10 -20
  74. package/src/column-view.tsx +8 -4
  75. package/src/combo-row.tsx +4 -1
  76. package/src/grid-view.tsx +3 -2
  77. package/src/internal/cells.tsx +174 -151
  78. package/src/internal/collection-index.ts +7 -14
  79. package/src/internal/collection-model.ts +211 -76
  80. package/src/internal/collection.ts +14 -13
  81. package/src/internal/controlled-sync.ts +8 -1
  82. package/src/internal/drop-down.tsx +112 -19
  83. package/src/internal/expansion.ts +52 -20
  84. package/src/internal/first-header.ts +23 -0
  85. package/src/internal/level-splice.ts +157 -0
  86. package/src/internal/selection.tsx +24 -19
  87. package/src/internal/tree-expansion.ts +43 -1
  88. package/src/internal/tree-order.ts +4 -10
  89. package/src/internal/use-collection.tsx +8 -2
  90. package/src/list-item-factory.tsx +2 -1
  91. package/src/list-view.tsx +10 -2
  92. package/src/types.ts +54 -24
@@ -1 +1 @@
1
- {"version":3,"file":"collection-index.js","sourceRoot":"","sources":["../../src/internal/collection-index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ListItem, ListSection } from \"../types.js\";\nimport { decodePartAt, encodePart } from \"./keys.js\";\n\ntype Level = {\n path: string;\n items: ListItem[];\n expandableFlags: boolean[];\n};\n\ntype SectionIdentity = Pick<ListSection, \"id\" | \"value\">;\n\ntype CollectionIndex = {\n isTree: boolean;\n groups: Level[];\n childLevel: (level: Level, slot: number) => Level | undefined;\n levelFor: (levelPath: string) => Level | undefined;\n itemAt: (levelPath: string, slot: number) => ListItem | undefined;\n sectionFor: (levelPath: string) => SectionIdentity | undefined;\n};\n\ntype IndexState = {\n isTree: boolean;\n groups: Level[];\n levels: Map<string, Level>;\n sections: Map<string, SectionIdentity>;\n};\n\ntype ParentItem = ListItem & { children: ListItem[] };\n\nconst hasChildren = (item: ListItem): item is ParentItem => item.children !== undefined && item.children.length > 0;\n\nfunction newLevel(state: IndexState, path: string, items: ListItem[]): Level {\n const expandableFlags = state.isTree ? items.map((item) => hasChildren(item)) : [];\n const level: Level = { path, items, expandableFlags };\n state.levels.set(path, level);\n\n return level;\n}\n\nfunction slotItems(state: IndexState, parent: Level, slot: number): ListItem[] | undefined {\n const owner = state.levels.get(parent.path) === parent ? parent : levelFor(state, parent.path);\n const item = owner?.items[slot];\n\n return item !== undefined && hasChildren(item) ? item.children : undefined;\n}\n\nfunction childLevel(state: IndexState, parent: Level, slot: number): Level | undefined {\n if (!state.isTree) {\n return undefined;\n }\n\n const path = parent.path + encodePart(String(slot));\n const cached = state.levels.get(path);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const items = slotItems(state, parent, slot);\n\n return items === undefined ? undefined : newLevel(state, path, items);\n}\n\nfunction descendPath(state: IndexState, levelPath: string, group: string): Level | undefined {\n let level = state.levels.get(encodePart(group));\n let offset = encodePart(group).length;\n\n while (level !== undefined && offset < levelPath.length) {\n const part = decodePartAt(levelPath, offset);\n\n if (part === null) {\n return undefined;\n }\n\n level = childLevel(state, level, Number(part));\n offset += encodePart(part).length;\n }\n\n return level;\n}\n\nfunction levelFor(state: IndexState, levelPath: string): Level | undefined {\n const cached = state.levels.get(levelPath);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const group = decodePartAt(levelPath, 0);\n\n return group === null ? undefined : descendPath(state, levelPath, group);\n}\n\nfunction buildGroups(state: IndexState, source: ListItem[], sections: ListSection[] | undefined): Level[] {\n if (sections === undefined) {\n return [newLevel(state, encodePart(\"0\"), source)];\n }\n\n return sections.map((section, group) => {\n const path = encodePart(String(group));\n state.sections.set(path, { id: section.id, value: section.value });\n\n return newLevel(state, path, section.data);\n });\n}\n\nfunction isTreeSource(source: ListItem[], sections: ListSection[] | undefined, isFlat: boolean): boolean {\n if (isFlat) {\n return false;\n }\n\n if (sections === undefined) {\n return source.some((item) => hasChildren(item));\n }\n\n return sections.some((section) => section.data.some((item) => hasChildren(item)));\n}\n\nfunction createCollectionIndex(\n items: ListItem[] | undefined,\n sections: ListSection[] | undefined,\n isFlat: boolean,\n): CollectionIndex {\n const source = items ?? [];\n\n const state: IndexState = {\n isTree: isTreeSource(source, sections, isFlat),\n groups: [],\n levels: new Map(),\n sections: new Map(),\n };\n\n state.groups = buildGroups(state, source, sections);\n\n return {\n isTree: state.isTree,\n groups: state.groups,\n childLevel: (level, slot) => childLevel(state, level, slot),\n levelFor: (levelPath) => levelFor(state, levelPath),\n itemAt: (levelPath, slot) => levelFor(state, levelPath)?.items[slot],\n sectionFor: (levelPath) => state.sections.get(levelPath),\n };\n}\n\nexport { createCollectionIndex, type CollectionIndex, type Level, type SectionIdentity };\n"]}
1
+ {"version":3,"file":"collection-index.js","sourceRoot":"","sources":["../../src/internal/collection-index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ListItem, ListSection } from \"../types.js\";\nimport { decodePartAt, encodePart } from \"./keys.js\";\n\ntype SectionIdentity = Pick<ListSection, \"id\" | \"value\">;\n\ntype Level = {\n path: string;\n items: ListItem[];\n expandableFlags: boolean[];\n section?: SectionIdentity | undefined;\n};\n\ntype CollectionIndex = {\n isTree: boolean;\n groups: Level[];\n childLevel: (level: Level, slot: number) => Level | undefined;\n};\n\ntype IndexState = {\n isTree: boolean;\n groups: Level[];\n levels: Map<string, Level>;\n};\n\ntype ParentItem = ListItem & { children: ListItem[] };\n\nconst hasChildren = (item: ListItem): item is ParentItem => item.children !== undefined && item.children.length > 0;\n\nfunction newLevel(state: IndexState, path: string, items: ListItem[]): Level {\n const expandableFlags = state.isTree ? items.map((item) => hasChildren(item)) : [];\n const level: Level = { path, items, expandableFlags };\n state.levels.set(path, level);\n\n return level;\n}\n\nfunction slotItems(state: IndexState, parent: Level, slot: number): ListItem[] | undefined {\n const owner = state.levels.get(parent.path) === parent ? parent : levelFor(state, parent.path);\n const item = owner?.items[slot];\n\n return item !== undefined && hasChildren(item) ? item.children : undefined;\n}\n\nfunction childLevel(state: IndexState, parent: Level, slot: number): Level | undefined {\n if (!state.isTree) {\n return undefined;\n }\n\n const path = parent.path + encodePart(String(slot));\n const cached = state.levels.get(path);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const items = slotItems(state, parent, slot);\n\n return items === undefined ? undefined : newLevel(state, path, items);\n}\n\nfunction descendPath(state: IndexState, levelPath: string, group: string): Level | undefined {\n let level = state.levels.get(encodePart(group));\n let offset = encodePart(group).length;\n\n while (level !== undefined && offset < levelPath.length) {\n const part = decodePartAt(levelPath, offset);\n\n if (part === null) {\n return undefined;\n }\n\n level = childLevel(state, level, Number(part));\n offset += encodePart(part).length;\n }\n\n return level;\n}\n\nfunction levelFor(state: IndexState, levelPath: string): Level | undefined {\n const cached = state.levels.get(levelPath);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const group = decodePartAt(levelPath, 0);\n\n return group === null ? undefined : descendPath(state, levelPath, group);\n}\n\nfunction buildGroups(state: IndexState, source: ListItem[], sections: ListSection[] | undefined): Level[] {\n if (sections === undefined) {\n return [newLevel(state, encodePart(\"0\"), source)];\n }\n\n return sections.map((section, group) => {\n const level = newLevel(state, encodePart(String(group)), section.data);\n level.section = { id: section.id, value: section.value };\n\n return level;\n });\n}\n\nfunction isTreeSource(source: ListItem[], sections: ListSection[] | undefined, isFlat: boolean): boolean {\n if (isFlat) {\n return false;\n }\n\n if (sections === undefined) {\n return source.some((item) => hasChildren(item));\n }\n\n return sections.some((section) => section.data.some((item) => hasChildren(item)));\n}\n\nfunction createCollectionIndex(\n items: ListItem[] | undefined,\n sections: ListSection[] | undefined,\n isFlat: boolean,\n): CollectionIndex {\n const source = items ?? [];\n\n const state: IndexState = {\n isTree: isTreeSource(source, sections, isFlat),\n groups: [],\n levels: new Map(),\n };\n\n state.groups = buildGroups(state, source, sections);\n\n return {\n isTree: state.isTree,\n groups: state.groups,\n childLevel: (level, slot) => childLevel(state, level, slot),\n };\n}\n\nexport { createCollectionIndex, type CollectionIndex, type Level };\n"]}
@@ -6,10 +6,17 @@ import type { CollectionIndex, Level } from "./collection-index.js";
6
6
  import type { TreeExpansion } from "./tree-expansion.js";
7
7
  type LevelStore = Gio.ListModel & LazyLevelStore;
8
8
  type SlotRef = {
9
+ key: string;
9
10
  store: LazyLevelStore;
10
11
  slot: number;
11
12
  };
13
+ type SlotItem = {
14
+ ref: SlotRef;
15
+ object: Gtk.StringObject;
16
+ };
12
17
  type ModelState = {
18
+ version: number;
19
+ listeners: Set<() => void>;
13
20
  root: CollectionRootStore | null;
14
21
  model: Gtk.FlattenListModel | null;
15
22
  groupStores: Map<number, LevelStore>;
@@ -19,15 +26,19 @@ type ModelState = {
19
26
  };
20
27
  type CollectionModel = {
21
28
  expansion: TreeExpansion;
29
+ subscribe: (onChange: () => void) => () => void;
30
+ getVersion: () => number;
31
+ isPending: (index: CollectionIndex) => boolean;
22
32
  rowAt: (position: number) => Gtk.TreeListRow | null;
23
33
  bind: (root: CollectionRootStore, model: Gtk.FlattenListModel) => void;
24
34
  clear: () => void;
25
- sync: (index: CollectionIndex) => void;
35
+ sync: (index: CollectionIndex, onSectionsFilled: () => void) => void;
26
36
  };
27
37
  type CollectionRootProps = {
28
38
  ref: Ref<CollectionRootStore>;
29
39
  };
30
40
  declare function slotRefFor(value: GObject.Object | null): SlotRef | null;
41
+ declare function levelStoreFor(value: GObject.Object | null): LazyLevelStore | null;
31
42
  declare function slotPathAt(store: LazyLevelStore, slot: number): string;
32
43
  declare function createCollectionModel(): CollectionModel;
33
44
  declare class CollectionRootStore extends GObject.Object implements Gio.ListModelImpl {
@@ -39,9 +50,9 @@ declare class CollectionRootStore extends GObject.Object implements Gio.ListMode
39
50
  }
40
51
  declare class LazyLevelStore extends GObject.Object implements Gio.ListModelImpl {
41
52
  itemsChanged: Gio.ListModel["itemsChanged"];
53
+ key: string;
42
54
  level: Level;
43
- refs: Map<number, SlotRef>;
44
- objects: Map<number, Gtk.StringObject>;
55
+ slots: Map<number, SlotItem>;
45
56
  childStores: Map<number, LevelStore>;
46
57
  private createItem;
47
58
  vfuncGetItemType(): bigint;
@@ -49,5 +60,5 @@ declare class LazyLevelStore extends GObject.Object implements Gio.ListModelImpl
49
60
  vfuncGetItem(position: number): GObject.Object | null;
50
61
  }
51
62
  declare const CollectionRoot: (props: CollectionRootProps) => ReactNode;
52
- export { CollectionRoot, createCollectionModel, slotPathAt, slotRefFor, type CollectionModel, type CollectionRootStore, type SlotRef, };
63
+ export { CollectionRoot, createCollectionModel, levelStoreFor, slotPathAt, slotRefFor, type CollectionModel, type CollectionRootStore, type LazyLevelStore, type SlotRef, };
53
64
  //# sourceMappingURL=collection-model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection-model.d.ts","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collection-model.d.ts","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"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"}
@@ -5,11 +5,17 @@ import { createElementComponent } from "@gtkx/react";
5
5
  import { registerClass } from "@gtkx/runtime";
6
6
  import { createCollectionIndex } from "./collection-index.js";
7
7
  import { encodePart } from "./keys.js";
8
- import { adoptIndex, createTreeExpansion, pruneSlots } from "./tree-expansion.js";
8
+ import { findSplice, hasSplice, matchMoves, NO_SPLICE, relocateEntries, relocateSlot, searchableSplice, } from "./level-splice.js";
9
+ import { adoptIndex, createTreeExpansion, pruneSlots, relocateSlots } from "./tree-expansion.js";
9
10
  const STORE_CLASS_KEY = Symbol.for("gtkx.components.lazy-level-store");
10
11
  const ROOT_CLASS_KEY = Symbol.for("gtkx.components.collection-root-store");
11
12
  const SLOTS_KEY = Symbol.for("gtkx.components.lazy-level-store.slots");
12
13
  const EMPTY_INDEX = createCollectionIndex(undefined, [], true);
14
+ const serial = { value: 0 };
15
+ function nextKey() {
16
+ serial.value += 1;
17
+ return String(serial.value);
18
+ }
13
19
  function sharedSlots() {
14
20
  const cached = Reflect.get(globalThis, SLOTS_KEY);
15
21
  if (cached instanceof WeakMap) {
@@ -37,13 +43,16 @@ function registeredRootClass() {
37
43
  Reflect.set(globalThis, ROOT_CLASS_KEY, CollectionRootStore);
38
44
  return CollectionRootStore;
39
45
  }
40
- function slotRefFor(value) {
46
+ function anySlotRefFor(value) {
41
47
  const item = value instanceof Gtk.TreeListRow ? value.getItem() : value;
42
- if (item === null) {
43
- return null;
44
- }
45
- const ref = sharedSlots().get(item);
46
- return ref === undefined || ref.slot === -1 ? null : ref;
48
+ return item === null ? null : (sharedSlots().get(item) ?? null);
49
+ }
50
+ function slotRefFor(value) {
51
+ const ref = anySlotRefFor(value);
52
+ return ref === null || ref.slot === -1 ? null : ref;
53
+ }
54
+ function levelStoreFor(value) {
55
+ return anySlotRefFor(value)?.store ?? null;
47
56
  }
48
57
  function slotPathAt(store, slot) {
49
58
  return store.level.path + encodePart(String(slot));
@@ -53,53 +62,89 @@ function newLevelStore(level) {
53
62
  store.level = level;
54
63
  return store;
55
64
  }
56
- function collectFlips(previous, next, overlap) {
65
+ function itemKeys(previous, next) {
66
+ return {
67
+ previousLength: previous.items.length,
68
+ nextLength: next.items.length,
69
+ previousKey: (slot) => previous.items[slot]?.id ?? "",
70
+ nextKey: (slot) => next.items[slot]?.id ?? "",
71
+ };
72
+ }
73
+ function groupKey(index, group) {
74
+ const level = index.groups[group];
75
+ return level?.section?.id ?? "";
76
+ }
77
+ function groupKeys(previous, next) {
78
+ return {
79
+ previousLength: previous.groups.length,
80
+ nextLength: next.groups.length,
81
+ previousKey: (group) => groupKey(previous, group),
82
+ nextKey: (group) => groupKey(next, group),
83
+ };
84
+ }
85
+ function isExpandableAt(level, slot) {
86
+ return level.expandableFlags[slot] ?? false;
87
+ }
88
+ function collectFlips(previous, next, splice) {
57
89
  const flipped = new Set();
58
90
  if (previous.expandableFlags.length === 0 && next.expandableFlags.length === 0) {
59
91
  return flipped;
60
92
  }
61
- for (let slot = 0; slot < overlap; slot++) {
62
- if ((previous.expandableFlags[slot] ?? false) !== (next.expandableFlags[slot] ?? false)) {
93
+ for (let slot = 0; slot < splice.start; slot++) {
94
+ if (isExpandableAt(previous, slot) !== isExpandableAt(next, slot)) {
63
95
  flipped.add(slot);
64
96
  }
65
97
  }
98
+ const shift = splice.added - splice.removed;
99
+ for (let slot = splice.start + splice.removed; slot < previous.items.length; slot++) {
100
+ if (isExpandableAt(previous, slot) !== isExpandableAt(next, slot + shift)) {
101
+ flipped.add(slot + shift);
102
+ }
103
+ }
66
104
  return flipped;
67
105
  }
106
+ function detachStore(store) {
107
+ for (const { ref } of store.slots.values()) {
108
+ ref.slot = -1;
109
+ }
110
+ for (const child of store.childStores.values()) {
111
+ detachStore(child);
112
+ }
113
+ }
68
114
  function pruneFlips(context, store, flipped) {
69
115
  if (flipped.size === 0) {
70
116
  return;
71
117
  }
72
118
  pruneSlots(context.expansion, store.level.path, (slot) => flipped.has(slot));
73
119
  for (const slot of flipped) {
74
- store.childStores.delete(slot);
75
- }
76
- }
77
- function detachRefs(store, nextLength) {
78
- for (const [slot, ref] of store.refs) {
79
- if (slot < nextLength) {
80
- continue;
120
+ const child = store.childStores.get(slot);
121
+ if (child !== undefined) {
122
+ detachStore(child);
123
+ store.childStores.delete(slot);
81
124
  }
82
- ref.slot = -1;
83
- store.refs.delete(slot);
84
- store.objects.delete(slot);
85
- store.childStores.delete(slot);
86
125
  }
87
126
  }
88
- function shrinkStore(context, store, previousLength, nextLength) {
89
- if (previousLength <= nextLength) {
127
+ function renewKeys(store, previous, from, to) {
128
+ if (from === to) {
90
129
  return;
91
130
  }
92
- detachRefs(store, nextLength);
93
- pruneSlots(context.expansion, store.level.path, (slot) => slot >= nextLength);
94
- }
95
- function emitTailSplice(store, previousLength, nextLength) {
96
- if (nextLength < previousLength) {
97
- store.itemsChanged(nextLength, previousLength - nextLength, 0);
98
- return;
131
+ for (const [slot, { ref }] of store.slots) {
132
+ if (slot >= from && slot < to && previous.items[slot]?.id !== store.level.items[slot]?.id) {
133
+ ref.key = nextKey();
134
+ }
99
135
  }
100
- if (nextLength > previousLength) {
101
- store.itemsChanged(previousLength, 0, nextLength - previousLength);
136
+ }
137
+ function relocateStore(context, store, keys, splice) {
138
+ const moves = matchMoves(keys, splice, store.slots.keys());
139
+ const shift = (slot) => relocateSlot(splice, slot);
140
+ store.slots = relocateEntries(store.slots, (slot) => relocateSlot(splice, slot, moves), ({ ref }) => {
141
+ ref.slot = -1;
142
+ });
143
+ for (const [slot, { ref }] of store.slots) {
144
+ ref.slot = slot;
102
145
  }
146
+ store.childStores = relocateEntries(store.childStores, shift, detachStore);
147
+ relocateSlots(context.expansion, store.level.path, shift);
103
148
  }
104
149
  function extendRuns(runs, slot) {
105
150
  const last = runs.at(-1);
@@ -123,18 +168,21 @@ function emitFlips(store, flipped) {
123
168
  }
124
169
  function syncLevel(context, store, level) {
125
170
  const previous = store.level;
126
- const previousLength = previous.items.length;
127
- const overlap = Math.min(previousLength, level.items.length);
128
- const flipped = collectFlips(previous, level, overlap);
171
+ const keys = itemKeys(previous, level);
172
+ const found = previous.items === level.items ? NO_SPLICE : findSplice(keys);
173
+ const splice = searchableSplice(found, found.added);
129
174
  store.level = level;
175
+ renewKeys(store, previous, found.start, splice.start);
176
+ if (hasSplice(splice)) {
177
+ relocateStore(context, store, keys, splice);
178
+ }
179
+ const flipped = collectFlips(previous, level, splice);
130
180
  pruneFlips(context, store, flipped);
131
- shrinkStore(context, store, previousLength, level.items.length);
132
- emitTailSplice(store, previousLength, level.items.length);
181
+ if (hasSplice(splice)) {
182
+ store.itemsChanged(splice.start, splice.removed, splice.added);
183
+ }
133
184
  emitFlips(store, flipped);
134
185
  for (const [slot, child] of store.childStores) {
135
- if (slot >= overlap || flipped.has(slot)) {
136
- continue;
137
- }
138
186
  const childLevel = context.index.childLevel(level, slot);
139
187
  if (childLevel !== undefined) {
140
188
  syncLevel(context, child, childLevel);
@@ -143,7 +191,7 @@ function syncLevel(context, store, level) {
143
191
  }
144
192
  function ensureChildStore(index, store, slot) {
145
193
  const existing = store.childStores.get(slot) ?? null;
146
- if (existing !== null || !(store.level.expandableFlags[slot] ?? false)) {
194
+ if (existing !== null || !isExpandableAt(store.level, slot)) {
147
195
  return existing;
148
196
  }
149
197
  const level = index.childLevel(store.level, slot);
@@ -174,30 +222,42 @@ function rowAt(state, position) {
174
222
  const item = state.model?.getItem(position);
175
223
  return item instanceof Gtk.TreeListRow ? item : null;
176
224
  }
177
- function pruneGroups(state, previous) {
178
- const hasModeChanged = previous.isTree !== state.index.isTree;
179
- for (const [group, store] of state.groupStores) {
180
- const isRemoved = group >= state.index.groups.length;
181
- if (isRemoved || hasModeChanged) {
182
- pruneSlots(state.expansion, store.level.path, () => true);
183
- state.trees.delete(store);
184
- }
185
- if (isRemoved) {
186
- state.groupStores.delete(group);
187
- }
188
- }
225
+ function dropGroup(state, store) {
226
+ detachStore(store);
227
+ state.trees.delete(store);
228
+ }
229
+ function replaceGroups(state, before) {
230
+ for (const store of state.groupStores.values()) {
231
+ dropGroup(state, store);
232
+ }
233
+ state.groupStores.clear();
234
+ state.expansion.expanded.clear();
235
+ state.expansion.slots.clear();
236
+ state.root?.itemsChanged(0, before, state.index.groups.length);
237
+ }
238
+ function addedRows(index, splice) {
239
+ return index.groups
240
+ .slice(splice.start, splice.start + splice.added)
241
+ .reduce((rows, level) => rows + level.items.length, 0);
189
242
  }
190
243
  function syncRoot(state, previous) {
191
- const before = previous.groups.length;
192
- const after = state.index.groups.length;
193
244
  if (previous.isTree !== state.index.isTree) {
194
- state.root?.itemsChanged(0, before, after);
245
+ replaceGroups(state, previous.groups.length);
195
246
  return;
196
247
  }
197
- if (before !== after) {
198
- const start = Math.min(before, after);
199
- state.root?.itemsChanged(start, before - start, after - start);
248
+ const keys = groupKeys(previous, state.index);
249
+ const found = findSplice(keys);
250
+ const splice = searchableSplice(found, addedRows(state.index, found));
251
+ if (!hasSplice(splice)) {
252
+ return;
200
253
  }
254
+ const moves = matchMoves(keys, splice, state.groupStores.keys());
255
+ const relocate = (group) => relocateSlot(splice, group, moves);
256
+ state.groupStores = relocateEntries(state.groupStores, relocate, (store) => {
257
+ dropGroup(state, store);
258
+ });
259
+ relocateSlots(state.expansion, "", relocate);
260
+ state.root?.itemsChanged(splice.start, splice.removed, splice.added);
201
261
  }
202
262
  function stepGroupStores(state, context) {
203
263
  for (const [group, store] of state.groupStores) {
@@ -207,7 +267,13 @@ function stepGroupStores(state, context) {
207
267
  }
208
268
  }
209
269
  }
210
- function syncModel(state, index) {
270
+ function rowCount(index) {
271
+ return index.groups.reduce((rows, level) => rows + level.items.length, 0);
272
+ }
273
+ function hasFilledSections(previous, index) {
274
+ return (rowCount(previous) === 0 && index.groups.some((level) => level.section !== undefined && level.items.length > 0));
275
+ }
276
+ function syncModel(state, index, onSectionsFilled) {
211
277
  if (state.root === null) {
212
278
  return;
213
279
  }
@@ -216,14 +282,20 @@ function syncModel(state, index) {
216
282
  state.index = index;
217
283
  state.expansion.isSyncing = true;
218
284
  try {
219
- pruneGroups(state, previous);
220
285
  syncRoot(state, previous);
221
286
  stepGroupStores(state, context);
287
+ if (hasFilledSections(previous, index)) {
288
+ onSectionsFilled();
289
+ }
222
290
  }
223
291
  finally {
224
292
  state.expansion.isSyncing = false;
225
293
  }
226
294
  adoptIndex(state.expansion, index);
295
+ state.version += 1;
296
+ for (const listener of state.listeners) {
297
+ listener();
298
+ }
227
299
  }
228
300
  function clearModel(state) {
229
301
  const root = state.root;
@@ -251,6 +323,8 @@ function clearModel(state) {
251
323
  }
252
324
  function createCollectionModel() {
253
325
  const state = {
326
+ version: 0,
327
+ listeners: new Set(),
254
328
  root: null,
255
329
  model: null,
256
330
  groupStores: new Map(),
@@ -260,6 +334,14 @@ function createCollectionModel() {
260
334
  };
261
335
  return {
262
336
  expansion: state.expansion,
337
+ subscribe: (onChange) => {
338
+ state.listeners.add(onChange);
339
+ return () => {
340
+ state.listeners.delete(onChange);
341
+ };
342
+ },
343
+ getVersion: () => state.version,
344
+ isPending: (index) => state.root !== null && state.index !== index,
263
345
  rowAt: (position) => rowAt(state, position),
264
346
  bind: (root, model) => {
265
347
  root.state = state;
@@ -269,8 +351,8 @@ function createCollectionModel() {
269
351
  clear: () => {
270
352
  clearModel(state);
271
353
  },
272
- sync: (index) => {
273
- syncModel(state, index);
354
+ sync: (index, onSectionsFilled) => {
355
+ syncModel(state, index, onSectionsFilled);
274
356
  },
275
357
  };
276
358
  }
@@ -297,17 +379,16 @@ class CollectionRootStore extends GObject.Object {
297
379
  }
298
380
  }
299
381
  class LazyLevelStore extends GObject.Object {
382
+ key = nextKey();
300
383
  level = { path: "", items: [], expandableFlags: [] };
301
- refs = new Map();
302
- objects = new Map();
384
+ slots = new Map();
303
385
  childStores = new Map();
304
386
  createItem(position) {
305
- const ref = { store: this, slot: position };
306
- const created = Gtk.StringObject.new("");
307
- this.refs.set(position, ref);
308
- this.objects.set(position, created);
309
- sharedSlots().set(created, ref);
310
- return created;
387
+ const ref = { key: nextKey(), store: this, slot: position };
388
+ const object = Gtk.StringObject.new("");
389
+ this.slots.set(position, { ref, object });
390
+ sharedSlots().set(object, ref);
391
+ return object;
311
392
  }
312
393
  vfuncGetItemType() {
313
394
  return GObject.TYPE_OBJECT;
@@ -319,9 +400,9 @@ class LazyLevelStore extends GObject.Object {
319
400
  if (position < 0 || position >= this.level.items.length) {
320
401
  return null;
321
402
  }
322
- return this.objects.get(position) ?? this.createItem(position);
403
+ return this.slots.get(position)?.object ?? this.createItem(position);
323
404
  }
324
405
  }
325
406
  const CollectionRoot = createElementComponent("GtkxCollectionRootStore", registeredRootClass());
326
- export { CollectionRoot, createCollectionModel, slotPathAt, slotRefFor, };
407
+ export { CollectionRoot, createCollectionModel, levelStoreFor, slotPathAt, slotRefFor, };
327
408
  //# sourceMappingURL=collection-model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection-model.js","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode, Ref } from \"react\";\nimport * as Gio from \"@gtkx/gi/gio\";\nimport * as GObject from \"@gtkx/gi/gobject\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { createElementComponent } from \"@gtkx/react\";\nimport { registerClass } from \"@gtkx/runtime\";\nimport type { CollectionIndex, Level } from \"./collection-index.js\";\nimport type { TreeExpansion } from \"./tree-expansion.js\";\nimport { createCollectionIndex } from \"./collection-index.js\";\nimport { encodePart } from \"./keys.js\";\nimport { adoptIndex, createTreeExpansion, pruneSlots } from \"./tree-expansion.js\";\n\ntype LevelStore = Gio.ListModel & LazyLevelStore;\n\ntype SlotRef = {\n store: LazyLevelStore;\n slot: number;\n};\n\ntype SyncContext = {\n index: CollectionIndex;\n expansion: TreeExpansion;\n};\n\ntype SlotRun = {\n start: number;\n length: number;\n};\n\ntype ModelState = {\n root: CollectionRootStore | null;\n model: Gtk.FlattenListModel | null;\n groupStores: Map<number, LevelStore>;\n trees: Map<LevelStore, Gtk.TreeListModel>;\n expansion: TreeExpansion;\n index: CollectionIndex;\n};\n\ntype CollectionModel = {\n expansion: TreeExpansion;\n rowAt: (position: number) => Gtk.TreeListRow | null;\n bind: (root: CollectionRootStore, model: Gtk.FlattenListModel) => void;\n clear: () => void;\n sync: (index: CollectionIndex) => void;\n};\n\ntype CollectionRootProps = { ref: Ref<CollectionRootStore> };\n\nconst STORE_CLASS_KEY = Symbol.for(\"gtkx.components.lazy-level-store\");\nconst ROOT_CLASS_KEY = Symbol.for(\"gtkx.components.collection-root-store\");\nconst SLOTS_KEY = Symbol.for(\"gtkx.components.lazy-level-store.slots\");\nconst EMPTY_INDEX = createCollectionIndex(undefined, [], true);\n\nfunction sharedSlots(): WeakMap<GObject.Object, SlotRef> {\n const cached: unknown = Reflect.get(globalThis, SLOTS_KEY);\n\n if (cached instanceof WeakMap) {\n return cached as WeakMap<GObject.Object, SlotRef>;\n }\n\n const created: WeakMap<GObject.Object, SlotRef> = new WeakMap();\n Reflect.set(globalThis, SLOTS_KEY, created);\n\n return created;\n}\n\nfunction registeredStoreClass(): typeof LazyLevelStore {\n const cached: unknown = Reflect.get(globalThis, STORE_CLASS_KEY);\n\n if (typeof cached === \"function\") {\n return cached as typeof LazyLevelStore;\n }\n\n registerClass(LazyLevelStore, { typeName: \"GtkxLazyLevelStore\", implements: [Gio.ListModel] });\n Reflect.set(globalThis, STORE_CLASS_KEY, LazyLevelStore);\n\n return LazyLevelStore;\n}\n\nfunction registeredRootClass(): unknown {\n const cached: unknown = Reflect.get(globalThis, ROOT_CLASS_KEY);\n\n if (typeof cached === \"function\") {\n return cached;\n }\n\n registerClass(CollectionRootStore, { typeName: \"GtkxCollectionRootStore\", implements: [Gio.ListModel] });\n Reflect.set(globalThis, ROOT_CLASS_KEY, CollectionRootStore);\n\n return CollectionRootStore;\n}\n\nfunction slotRefFor(value: GObject.Object | null): SlotRef | null {\n const item = value instanceof Gtk.TreeListRow ? value.getItem() : value;\n\n if (item === null) {\n return null;\n }\n\n const ref = sharedSlots().get(item);\n\n return ref === undefined || ref.slot === -1 ? null : ref;\n}\n\nfunction slotPathAt(store: LazyLevelStore, slot: number): string {\n return store.level.path + encodePart(String(slot));\n}\n\nfunction newLevelStore(level: Level): LevelStore {\n const store = new (registeredStoreClass())() as LevelStore;\n store.level = level;\n\n return store;\n}\n\nfunction collectFlips(previous: Level, next: Level, overlap: number): Set<number> {\n const flipped: Set<number> = new Set();\n\n if (previous.expandableFlags.length === 0 && next.expandableFlags.length === 0) {\n return flipped;\n }\n\n for (let slot = 0; slot < overlap; slot++) {\n if ((previous.expandableFlags[slot] ?? false) !== (next.expandableFlags[slot] ?? false)) {\n flipped.add(slot);\n }\n }\n\n return flipped;\n}\n\nfunction pruneFlips(context: SyncContext, store: LevelStore, flipped: Set<number>): void {\n if (flipped.size === 0) {\n return;\n }\n\n pruneSlots(context.expansion, store.level.path, (slot) => flipped.has(slot));\n\n for (const slot of flipped) {\n store.childStores.delete(slot);\n }\n}\n\nfunction detachRefs(store: LevelStore, nextLength: number): void {\n for (const [slot, ref] of store.refs) {\n if (slot < nextLength) {\n continue;\n }\n\n ref.slot = -1;\n store.refs.delete(slot);\n store.objects.delete(slot);\n store.childStores.delete(slot);\n }\n}\n\nfunction shrinkStore(context: SyncContext, store: LevelStore, previousLength: number, nextLength: number): void {\n if (previousLength <= nextLength) {\n return;\n }\n\n detachRefs(store, nextLength);\n pruneSlots(context.expansion, store.level.path, (slot) => slot >= nextLength);\n}\n\nfunction emitTailSplice(store: LevelStore, previousLength: number, nextLength: number): void {\n if (nextLength < previousLength) {\n store.itemsChanged(nextLength, previousLength - nextLength, 0);\n\n return;\n }\n\n if (nextLength > previousLength) {\n store.itemsChanged(previousLength, 0, nextLength - previousLength);\n }\n}\n\nfunction extendRuns(runs: SlotRun[], slot: number): void {\n const last = runs.at(-1);\n\n if (last !== undefined && last.start + last.length === slot) {\n last.length += 1;\n\n return;\n }\n\n runs.push({ start: slot, length: 1 });\n}\n\nfunction collectFlipRuns(flipped: Set<number>): SlotRun[] {\n const runs: SlotRun[] = [];\n\n for (const slot of flipped) {\n extendRuns(runs, slot);\n }\n\n return runs;\n}\n\nfunction emitFlips(store: LevelStore, flipped: Set<number>): void {\n for (const run of collectFlipRuns(flipped)) {\n store.itemsChanged(run.start, run.length, run.length);\n }\n}\n\nfunction syncLevel(context: SyncContext, store: LevelStore, level: Level): void {\n const previous = store.level;\n const previousLength = previous.items.length;\n const overlap = Math.min(previousLength, level.items.length);\n const flipped = collectFlips(previous, level, overlap);\n store.level = level;\n pruneFlips(context, store, flipped);\n shrinkStore(context, store, previousLength, level.items.length);\n emitTailSplice(store, previousLength, level.items.length);\n emitFlips(store, flipped);\n\n for (const [slot, child] of store.childStores) {\n if (slot >= overlap || flipped.has(slot)) {\n continue;\n }\n\n const childLevel = context.index.childLevel(level, slot);\n\n if (childLevel !== undefined) {\n syncLevel(context, child, childLevel);\n }\n }\n}\n\nfunction ensureChildStore(index: CollectionIndex, store: LazyLevelStore, slot: number): LevelStore | null {\n const existing = store.childStores.get(slot) ?? null;\n\n if (existing !== null || !(store.level.expandableFlags[slot] ?? false)) {\n return existing;\n }\n\n const level = index.childLevel(store.level, slot);\n\n if (level === undefined) {\n return null;\n }\n\n const created = newLevelStore(level);\n store.childStores.set(slot, created);\n\n return created;\n}\n\nfunction childStoreFor(state: ModelState, object: GObject.Object): Gio.ListModel | null {\n const ref = slotRefFor(object);\n\n if (ref === null) {\n return null;\n }\n\n return ensureChildStore(state.index, ref.store, ref.slot);\n}\n\nfunction treeFor(state: ModelState, store: LevelStore): Gtk.TreeListModel {\n const existing = state.trees.get(store);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const created = Gtk.TreeListModel.new(store, false, false, (object) => childStoreFor(state, object));\n state.trees.set(store, created);\n\n return created;\n}\n\nfunction rowAt(state: ModelState, position: number): Gtk.TreeListRow | null {\n const item = state.model?.getItem(position);\n\n return item instanceof Gtk.TreeListRow ? item : null;\n}\n\nfunction pruneGroups(state: ModelState, previous: CollectionIndex): void {\n const hasModeChanged = previous.isTree !== state.index.isTree;\n\n for (const [group, store] of state.groupStores) {\n const isRemoved = group >= state.index.groups.length;\n\n if (isRemoved || hasModeChanged) {\n pruneSlots(state.expansion, store.level.path, () => true);\n state.trees.delete(store);\n }\n\n if (isRemoved) {\n state.groupStores.delete(group);\n }\n }\n}\n\nfunction syncRoot(state: ModelState, previous: CollectionIndex): void {\n const before = previous.groups.length;\n const after = state.index.groups.length;\n\n if (previous.isTree !== state.index.isTree) {\n state.root?.itemsChanged(0, before, after);\n\n return;\n }\n\n if (before !== after) {\n const start = Math.min(before, after);\n state.root?.itemsChanged(start, before - start, after - start);\n }\n}\n\nfunction stepGroupStores(state: ModelState, context: SyncContext): void {\n for (const [group, store] of state.groupStores) {\n const level = context.index.groups[group];\n\n if (level !== undefined && store.level !== level) {\n syncLevel(context, store, level);\n }\n }\n}\n\nfunction syncModel(state: ModelState, index: CollectionIndex): void {\n if (state.root === null) {\n return;\n }\n\n const context: SyncContext = { index, expansion: state.expansion };\n const previous = state.index;\n state.index = index;\n state.expansion.isSyncing = true;\n\n try {\n pruneGroups(state, previous);\n syncRoot(state, previous);\n stepGroupStores(state, context);\n } finally {\n state.expansion.isSyncing = false;\n }\n\n adoptIndex(state.expansion, index);\n}\n\nfunction clearModel(state: ModelState): void {\n const root = state.root;\n const previousLength = state.index.groups.length;\n state.expansion.isSyncing = true;\n\n try {\n if (root !== null) {\n root.state = null;\n }\n\n state.root = null;\n state.model = null;\n state.index = EMPTY_INDEX;\n state.groupStores.clear();\n state.trees.clear();\n state.expansion.expanded.clear();\n state.expansion.slots.clear();\n adoptIndex(state.expansion, EMPTY_INDEX);\n\n if (previousLength > 0) {\n root?.itemsChanged(0, previousLength, 0);\n }\n } finally {\n state.expansion.isSyncing = false;\n }\n}\n\nfunction createCollectionModel(): CollectionModel {\n const state: ModelState = {\n root: null,\n model: null,\n groupStores: new Map(),\n trees: new Map(),\n expansion: createTreeExpansion(EMPTY_INDEX),\n index: EMPTY_INDEX,\n };\n\n return {\n expansion: state.expansion,\n rowAt: (position) => rowAt(state, position),\n bind: (root, model) => {\n root.state = state;\n state.root = root;\n state.model = model;\n },\n clear: () => {\n clearModel(state);\n },\n sync: (index) => {\n syncModel(state, index);\n },\n };\n}\n\nclass CollectionRootStore extends GObject.Object implements Gio.ListModelImpl {\n declare itemsChanged: Gio.ListModel[\"itemsChanged\"];\n state: ModelState | null = null;\n\n vfuncGetItemType(): bigint {\n return GObject.TYPE_OBJECT;\n }\n\n vfuncGetNItems(): number {\n return this.state?.index.groups.length ?? 0;\n }\n\n vfuncGetItem(position: number): GObject.Object | null {\n const state = this.state;\n const level = state?.index.groups[position];\n\n if (state === null || level === undefined) {\n return null;\n }\n\n let store = state.groupStores.get(position);\n\n if (store === undefined) {\n store = newLevelStore(level);\n state.groupStores.set(position, store);\n }\n\n return state.index.isTree ? treeFor(state, store) : store;\n }\n}\n\nclass LazyLevelStore extends GObject.Object implements Gio.ListModelImpl {\n declare itemsChanged: Gio.ListModel[\"itemsChanged\"];\n level: Level = { path: \"\", items: [], expandableFlags: [] };\n refs: Map<number, SlotRef> = new Map();\n objects: Map<number, Gtk.StringObject> = new Map();\n childStores: Map<number, LevelStore> = new Map();\n\n private createItem(position: number): Gtk.StringObject {\n const ref = { store: this, slot: position };\n const created = Gtk.StringObject.new(\"\");\n this.refs.set(position, ref);\n this.objects.set(position, created);\n sharedSlots().set(created, ref);\n\n return created;\n }\n\n vfuncGetItemType(): bigint {\n return GObject.TYPE_OBJECT;\n }\n\n vfuncGetNItems(): number {\n return this.level.items.length;\n }\n\n vfuncGetItem(position: number): GObject.Object | null {\n if (position < 0 || position >= this.level.items.length) {\n return null;\n }\n\n return this.objects.get(position) ?? this.createItem(position);\n }\n}\n\nconst CollectionRoot: (props: CollectionRootProps) => ReactNode = createElementComponent<CollectionRootProps>(\n \"GtkxCollectionRootStore\",\n registeredRootClass(),\n);\n\nexport {\n CollectionRoot,\n createCollectionModel,\n slotPathAt,\n slotRefFor,\n type CollectionModel,\n type CollectionRootStore,\n type SlotRef,\n};\n"]}
1
+ {"version":3,"file":"collection-model.js","sourceRoot":"","sources":["../../src/internal/collection-model.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode, Ref } from \"react\";\nimport * as Gio from \"@gtkx/gi/gio\";\nimport * as GObject from \"@gtkx/gi/gobject\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { createElementComponent } from \"@gtkx/react\";\nimport { registerClass } from \"@gtkx/runtime\";\nimport type { CollectionIndex, Level } from \"./collection-index.js\";\nimport type { TreeExpansion } from \"./tree-expansion.js\";\nimport { createCollectionIndex } from \"./collection-index.js\";\nimport type { LevelKeys, Relocate, Splice } from \"./level-splice.js\";\nimport { encodePart } from \"./keys.js\";\nimport {\n findSplice,\n hasSplice,\n matchMoves,\n NO_SPLICE,\n relocateEntries,\n relocateSlot,\n searchableSplice,\n} from \"./level-splice.js\";\nimport { adoptIndex, createTreeExpansion, pruneSlots, relocateSlots } from \"./tree-expansion.js\";\n\ntype LevelStore = Gio.ListModel & LazyLevelStore;\n\ntype SlotRef = {\n key: string;\n store: LazyLevelStore;\n slot: number;\n};\n\ntype SlotItem = {\n ref: SlotRef;\n object: Gtk.StringObject;\n};\n\ntype SyncContext = {\n index: CollectionIndex;\n expansion: TreeExpansion;\n};\n\ntype SlotRun = {\n start: number;\n length: number;\n};\n\ntype Serial = {\n value: number;\n};\n\ntype ModelState = {\n version: number;\n listeners: Set<() => void>;\n root: CollectionRootStore | null;\n model: Gtk.FlattenListModel | null;\n groupStores: Map<number, LevelStore>;\n trees: Map<LevelStore, Gtk.TreeListModel>;\n expansion: TreeExpansion;\n index: CollectionIndex;\n};\n\ntype CollectionModel = {\n expansion: TreeExpansion;\n subscribe: (onChange: () => void) => () => void;\n getVersion: () => number;\n isPending: (index: CollectionIndex) => boolean;\n rowAt: (position: number) => Gtk.TreeListRow | null;\n bind: (root: CollectionRootStore, model: Gtk.FlattenListModel) => void;\n clear: () => void;\n sync: (index: CollectionIndex, onSectionsFilled: () => void) => void;\n};\n\ntype CollectionRootProps = { ref: Ref<CollectionRootStore> };\n\nconst STORE_CLASS_KEY = Symbol.for(\"gtkx.components.lazy-level-store\");\nconst ROOT_CLASS_KEY = Symbol.for(\"gtkx.components.collection-root-store\");\nconst SLOTS_KEY = Symbol.for(\"gtkx.components.lazy-level-store.slots\");\nconst EMPTY_INDEX = createCollectionIndex(undefined, [], true);\nconst serial: Serial = { value: 0 };\n\nfunction nextKey(): string {\n serial.value += 1;\n\n return String(serial.value);\n}\n\nfunction sharedSlots(): WeakMap<GObject.Object, SlotRef> {\n const cached: unknown = Reflect.get(globalThis, SLOTS_KEY);\n\n if (cached instanceof WeakMap) {\n return cached as WeakMap<GObject.Object, SlotRef>;\n }\n\n const created: WeakMap<GObject.Object, SlotRef> = new WeakMap();\n Reflect.set(globalThis, SLOTS_KEY, created);\n\n return created;\n}\n\nfunction registeredStoreClass(): typeof LazyLevelStore {\n const cached: unknown = Reflect.get(globalThis, STORE_CLASS_KEY);\n\n if (typeof cached === \"function\") {\n return cached as typeof LazyLevelStore;\n }\n\n registerClass(LazyLevelStore, { typeName: \"GtkxLazyLevelStore\", implements: [Gio.ListModel] });\n Reflect.set(globalThis, STORE_CLASS_KEY, LazyLevelStore);\n\n return LazyLevelStore;\n}\n\nfunction registeredRootClass(): unknown {\n const cached: unknown = Reflect.get(globalThis, ROOT_CLASS_KEY);\n\n if (typeof cached === \"function\") {\n return cached;\n }\n\n registerClass(CollectionRootStore, { typeName: \"GtkxCollectionRootStore\", implements: [Gio.ListModel] });\n Reflect.set(globalThis, ROOT_CLASS_KEY, CollectionRootStore);\n\n return CollectionRootStore;\n}\n\nfunction anySlotRefFor(value: GObject.Object | null): SlotRef | null {\n const item = value instanceof Gtk.TreeListRow ? value.getItem() : value;\n\n return item === null ? null : (sharedSlots().get(item) ?? null);\n}\n\nfunction slotRefFor(value: GObject.Object | null): SlotRef | null {\n const ref = anySlotRefFor(value);\n\n return ref === null || ref.slot === -1 ? null : ref;\n}\n\nfunction levelStoreFor(value: GObject.Object | null): LazyLevelStore | null {\n return anySlotRefFor(value)?.store ?? null;\n}\n\nfunction slotPathAt(store: LazyLevelStore, slot: number): string {\n return store.level.path + encodePart(String(slot));\n}\n\nfunction newLevelStore(level: Level): LevelStore {\n const store = new (registeredStoreClass())() as LevelStore;\n store.level = level;\n\n return store;\n}\n\nfunction itemKeys(previous: Level, next: Level): LevelKeys {\n return {\n previousLength: previous.items.length,\n nextLength: next.items.length,\n previousKey: (slot) => previous.items[slot]?.id ?? \"\",\n nextKey: (slot) => next.items[slot]?.id ?? \"\",\n };\n}\n\nfunction groupKey(index: CollectionIndex, group: number): string {\n const level = index.groups[group];\n\n return level?.section?.id ?? \"\";\n}\n\nfunction groupKeys(previous: CollectionIndex, next: CollectionIndex): LevelKeys {\n return {\n previousLength: previous.groups.length,\n nextLength: next.groups.length,\n previousKey: (group) => groupKey(previous, group),\n nextKey: (group) => groupKey(next, group),\n };\n}\n\nfunction isExpandableAt(level: Level, slot: number): boolean {\n return level.expandableFlags[slot] ?? false;\n}\n\nfunction collectFlips(previous: Level, next: Level, splice: Splice): Set<number> {\n const flipped: Set<number> = new Set();\n\n if (previous.expandableFlags.length === 0 && next.expandableFlags.length === 0) {\n return flipped;\n }\n\n for (let slot = 0; slot < splice.start; slot++) {\n if (isExpandableAt(previous, slot) !== isExpandableAt(next, slot)) {\n flipped.add(slot);\n }\n }\n\n const shift = splice.added - splice.removed;\n\n for (let slot = splice.start + splice.removed; slot < previous.items.length; slot++) {\n if (isExpandableAt(previous, slot) !== isExpandableAt(next, slot + shift)) {\n flipped.add(slot + shift);\n }\n }\n\n return flipped;\n}\n\nfunction detachStore(store: LevelStore): void {\n for (const { ref } of store.slots.values()) {\n ref.slot = -1;\n }\n\n for (const child of store.childStores.values()) {\n detachStore(child);\n }\n}\n\nfunction pruneFlips(context: SyncContext, store: LevelStore, flipped: Set<number>): void {\n if (flipped.size === 0) {\n return;\n }\n\n pruneSlots(context.expansion, store.level.path, (slot) => flipped.has(slot));\n\n for (const slot of flipped) {\n const child = store.childStores.get(slot);\n\n if (child !== undefined) {\n detachStore(child);\n store.childStores.delete(slot);\n }\n }\n}\n\nfunction renewKeys(store: LevelStore, previous: Level, from: number, to: number): void {\n if (from === to) {\n return;\n }\n\n for (const [slot, { ref }] of store.slots) {\n if (slot >= from && slot < to && previous.items[slot]?.id !== store.level.items[slot]?.id) {\n ref.key = nextKey();\n }\n }\n}\n\nfunction relocateStore(context: SyncContext, store: LevelStore, keys: LevelKeys, splice: Splice): void {\n const moves = matchMoves(keys, splice, store.slots.keys());\n const shift: Relocate = (slot) => relocateSlot(splice, slot);\n\n store.slots = relocateEntries(\n store.slots,\n (slot) => relocateSlot(splice, slot, moves),\n ({ ref }) => {\n ref.slot = -1;\n },\n );\n\n for (const [slot, { ref }] of store.slots) {\n ref.slot = slot;\n }\n\n store.childStores = relocateEntries(store.childStores, shift, detachStore);\n relocateSlots(context.expansion, store.level.path, shift);\n}\n\nfunction extendRuns(runs: SlotRun[], slot: number): void {\n const last = runs.at(-1);\n\n if (last !== undefined && last.start + last.length === slot) {\n last.length += 1;\n\n return;\n }\n\n runs.push({ start: slot, length: 1 });\n}\n\nfunction collectFlipRuns(flipped: Set<number>): SlotRun[] {\n const runs: SlotRun[] = [];\n\n for (const slot of flipped) {\n extendRuns(runs, slot);\n }\n\n return runs;\n}\n\nfunction emitFlips(store: LevelStore, flipped: Set<number>): void {\n for (const run of collectFlipRuns(flipped)) {\n store.itemsChanged(run.start, run.length, run.length);\n }\n}\n\nfunction syncLevel(context: SyncContext, store: LevelStore, level: Level): void {\n const previous = store.level;\n const keys = itemKeys(previous, level);\n const found = previous.items === level.items ? NO_SPLICE : findSplice(keys);\n const splice = searchableSplice(found, found.added);\n store.level = level;\n renewKeys(store, previous, found.start, splice.start);\n\n if (hasSplice(splice)) {\n relocateStore(context, store, keys, splice);\n }\n\n const flipped = collectFlips(previous, level, splice);\n pruneFlips(context, store, flipped);\n\n if (hasSplice(splice)) {\n store.itemsChanged(splice.start, splice.removed, splice.added);\n }\n\n emitFlips(store, flipped);\n\n for (const [slot, child] of store.childStores) {\n const childLevel = context.index.childLevel(level, slot);\n\n if (childLevel !== undefined) {\n syncLevel(context, child, childLevel);\n }\n }\n}\n\nfunction ensureChildStore(index: CollectionIndex, store: LazyLevelStore, slot: number): LevelStore | null {\n const existing = store.childStores.get(slot) ?? null;\n\n if (existing !== null || !isExpandableAt(store.level, slot)) {\n return existing;\n }\n\n const level = index.childLevel(store.level, slot);\n\n if (level === undefined) {\n return null;\n }\n\n const created = newLevelStore(level);\n store.childStores.set(slot, created);\n\n return created;\n}\n\nfunction childStoreFor(state: ModelState, object: GObject.Object): Gio.ListModel | null {\n const ref = slotRefFor(object);\n\n if (ref === null) {\n return null;\n }\n\n return ensureChildStore(state.index, ref.store, ref.slot);\n}\n\nfunction treeFor(state: ModelState, store: LevelStore): Gtk.TreeListModel {\n const existing = state.trees.get(store);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const created = Gtk.TreeListModel.new(store, false, false, (object) => childStoreFor(state, object));\n state.trees.set(store, created);\n\n return created;\n}\n\nfunction rowAt(state: ModelState, position: number): Gtk.TreeListRow | null {\n const item = state.model?.getItem(position);\n\n return item instanceof Gtk.TreeListRow ? item : null;\n}\n\nfunction dropGroup(state: ModelState, store: LevelStore): void {\n detachStore(store);\n state.trees.delete(store);\n}\n\nfunction replaceGroups(state: ModelState, before: number): void {\n for (const store of state.groupStores.values()) {\n dropGroup(state, store);\n }\n\n state.groupStores.clear();\n state.expansion.expanded.clear();\n state.expansion.slots.clear();\n state.root?.itemsChanged(0, before, state.index.groups.length);\n}\n\nfunction addedRows(index: CollectionIndex, splice: Splice): number {\n return index.groups\n .slice(splice.start, splice.start + splice.added)\n .reduce((rows, level) => rows + level.items.length, 0);\n}\n\nfunction syncRoot(state: ModelState, previous: CollectionIndex): void {\n if (previous.isTree !== state.index.isTree) {\n replaceGroups(state, previous.groups.length);\n\n return;\n }\n\n const keys = groupKeys(previous, state.index);\n const found = findSplice(keys);\n const splice = searchableSplice(found, addedRows(state.index, found));\n\n if (!hasSplice(splice)) {\n return;\n }\n\n const moves = matchMoves(keys, splice, state.groupStores.keys());\n const relocate: Relocate = (group) => relocateSlot(splice, group, moves);\n state.groupStores = relocateEntries(state.groupStores, relocate, (store) => {\n dropGroup(state, store);\n });\n relocateSlots(state.expansion, \"\", relocate);\n\n state.root?.itemsChanged(splice.start, splice.removed, splice.added);\n}\n\nfunction stepGroupStores(state: ModelState, context: SyncContext): void {\n for (const [group, store] of state.groupStores) {\n const level = context.index.groups[group];\n\n if (level !== undefined && store.level !== level) {\n syncLevel(context, store, level);\n }\n }\n}\n\nfunction rowCount(index: CollectionIndex): number {\n return index.groups.reduce((rows, level) => rows + level.items.length, 0);\n}\n\nfunction hasFilledSections(previous: CollectionIndex, index: CollectionIndex): boolean {\n return (\n rowCount(previous) === 0 && index.groups.some((level) => level.section !== undefined && level.items.length > 0)\n );\n}\n\nfunction syncModel(state: ModelState, index: CollectionIndex, onSectionsFilled: () => void): void {\n if (state.root === null) {\n return;\n }\n\n const context: SyncContext = { index, expansion: state.expansion };\n const previous = state.index;\n state.index = index;\n state.expansion.isSyncing = true;\n\n try {\n syncRoot(state, previous);\n stepGroupStores(state, context);\n\n if (hasFilledSections(previous, index)) {\n onSectionsFilled();\n }\n } finally {\n state.expansion.isSyncing = false;\n }\n\n adoptIndex(state.expansion, index);\n state.version += 1;\n\n for (const listener of state.listeners) {\n listener();\n }\n}\n\nfunction clearModel(state: ModelState): void {\n const root = state.root;\n const previousLength = state.index.groups.length;\n state.expansion.isSyncing = true;\n\n try {\n if (root !== null) {\n root.state = null;\n }\n\n state.root = null;\n state.model = null;\n state.index = EMPTY_INDEX;\n state.groupStores.clear();\n state.trees.clear();\n state.expansion.expanded.clear();\n state.expansion.slots.clear();\n adoptIndex(state.expansion, EMPTY_INDEX);\n\n if (previousLength > 0) {\n root?.itemsChanged(0, previousLength, 0);\n }\n } finally {\n state.expansion.isSyncing = false;\n }\n}\n\nfunction createCollectionModel(): CollectionModel {\n const state: ModelState = {\n version: 0,\n listeners: new Set(),\n root: null,\n model: null,\n groupStores: new Map(),\n trees: new Map(),\n expansion: createTreeExpansion(EMPTY_INDEX),\n index: EMPTY_INDEX,\n };\n\n return {\n expansion: state.expansion,\n subscribe: (onChange) => {\n state.listeners.add(onChange);\n\n return () => {\n state.listeners.delete(onChange);\n };\n },\n getVersion: () => state.version,\n isPending: (index) => state.root !== null && state.index !== index,\n rowAt: (position) => rowAt(state, position),\n bind: (root, model) => {\n root.state = state;\n state.root = root;\n state.model = model;\n },\n clear: () => {\n clearModel(state);\n },\n sync: (index, onSectionsFilled) => {\n syncModel(state, index, onSectionsFilled);\n },\n };\n}\n\nclass CollectionRootStore extends GObject.Object implements Gio.ListModelImpl {\n declare itemsChanged: Gio.ListModel[\"itemsChanged\"];\n state: ModelState | null = null;\n\n vfuncGetItemType(): bigint {\n return GObject.TYPE_OBJECT;\n }\n\n vfuncGetNItems(): number {\n return this.state?.index.groups.length ?? 0;\n }\n\n vfuncGetItem(position: number): GObject.Object | null {\n const state = this.state;\n const level = state?.index.groups[position];\n\n if (state === null || level === undefined) {\n return null;\n }\n\n let store = state.groupStores.get(position);\n\n if (store === undefined) {\n store = newLevelStore(level);\n state.groupStores.set(position, store);\n }\n\n return state.index.isTree ? treeFor(state, store) : store;\n }\n}\n\nclass LazyLevelStore extends GObject.Object implements Gio.ListModelImpl {\n declare itemsChanged: Gio.ListModel[\"itemsChanged\"];\n key: string = nextKey();\n level: Level = { path: \"\", items: [], expandableFlags: [] };\n slots: Map<number, SlotItem> = new Map();\n childStores: Map<number, LevelStore> = new Map();\n\n private createItem(position: number): Gtk.StringObject {\n const ref = { key: nextKey(), store: this, slot: position };\n const object = Gtk.StringObject.new(\"\");\n this.slots.set(position, { ref, object });\n sharedSlots().set(object, ref);\n\n return object;\n }\n\n vfuncGetItemType(): bigint {\n return GObject.TYPE_OBJECT;\n }\n\n vfuncGetNItems(): number {\n return this.level.items.length;\n }\n\n vfuncGetItem(position: number): GObject.Object | null {\n if (position < 0 || position >= this.level.items.length) {\n return null;\n }\n\n return this.slots.get(position)?.object ?? this.createItem(position);\n }\n}\n\nconst CollectionRoot: (props: CollectionRootProps) => ReactNode = createElementComponent<CollectionRootProps>(\n \"GtkxCollectionRootStore\",\n registeredRootClass(),\n);\n\nexport {\n CollectionRoot,\n createCollectionModel,\n levelStoreFor,\n slotPathAt,\n slotRefFor,\n type CollectionModel,\n type CollectionRootStore,\n type LazyLevelStore,\n type SlotRef,\n};\n"]}
@@ -1,15 +1,15 @@
1
1
  import type * as Gtk from "@gtkx/gi/gtk";
2
2
  import type { ListItem } from "../types.js";
3
- import type { CollectionIndex, SectionIdentity } from "./collection-index.js";
3
+ import type { CollectionIndex } from "./collection-index.js";
4
4
  import type { CollectionModel, SlotRef } from "./collection-model.js";
5
5
  import type { MatchedRows } from "./tree-order.js";
6
- type Collection = Pick<CollectionModel, "expansion" | "rowAt"> & {
6
+ type Collection = Pick<CollectionModel, "expansion" | "rowAt" | "subscribe" | "getVersion"> & {
7
7
  isTree: boolean;
8
8
  itemAt: (ref: SlotRef) => ListItem | undefined;
9
- sectionFor: (levelPath: string) => SectionIdentity | undefined;
10
9
  idAt: (position: number) => string | null;
11
10
  idsAt: (positions: number[]) => string[];
12
11
  pathAt: (position: number) => string | null;
12
+ isPending: () => boolean;
13
13
  positionFor: (id: string) => number;
14
14
  rowsFor: (ids: string[]) => MatchedRows;
15
15
  };