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

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 (75) hide show
  1. package/README.md +8 -168
  2. package/dist/column-view.d.ts.map +1 -1
  3. package/dist/column-view.js +19 -9
  4. package/dist/column-view.js.map +1 -1
  5. package/dist/index.d.ts +3 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/internal/cells.d.ts +8 -1
  10. package/dist/internal/cells.d.ts.map +1 -1
  11. package/dist/internal/cells.js +84 -19
  12. package/dist/internal/cells.js.map +1 -1
  13. package/dist/internal/collection-index.d.ts +3 -2
  14. package/dist/internal/collection-index.d.ts.map +1 -1
  15. package/dist/internal/collection-index.js +3 -3
  16. package/dist/internal/collection-index.js.map +1 -1
  17. package/dist/internal/collection-model.d.ts +23 -2
  18. package/dist/internal/collection-model.d.ts.map +1 -1
  19. package/dist/internal/collection-model.js +118 -98
  20. package/dist/internal/collection-model.js.map +1 -1
  21. package/dist/internal/collection.d.ts +5 -4
  22. package/dist/internal/collection.d.ts.map +1 -1
  23. package/dist/internal/collection.js +20 -21
  24. package/dist/internal/collection.js.map +1 -1
  25. package/dist/internal/controlled-sync.d.ts +6 -8
  26. package/dist/internal/controlled-sync.d.ts.map +1 -1
  27. package/dist/internal/controlled-sync.js +3 -3
  28. package/dist/internal/controlled-sync.js.map +1 -1
  29. package/dist/internal/drop-down.d.ts.map +1 -1
  30. package/dist/internal/drop-down.js +43 -44
  31. package/dist/internal/drop-down.js.map +1 -1
  32. package/dist/internal/expansion.js +4 -4
  33. package/dist/internal/expansion.js.map +1 -1
  34. package/dist/internal/selection.d.ts +1 -0
  35. package/dist/internal/selection.d.ts.map +1 -1
  36. package/dist/internal/selection.js +6 -6
  37. package/dist/internal/selection.js.map +1 -1
  38. package/dist/internal/tree-expansion.d.ts.map +1 -1
  39. package/dist/internal/tree-expansion.js +2 -11
  40. package/dist/internal/tree-expansion.js.map +1 -1
  41. package/dist/internal/tree-order.d.ts.map +1 -1
  42. package/dist/internal/tree-order.js +32 -76
  43. package/dist/internal/tree-order.js.map +1 -1
  44. package/dist/internal/use-collection.d.ts +5 -1
  45. package/dist/internal/use-collection.d.ts.map +1 -1
  46. package/dist/internal/use-collection.js +21 -7
  47. package/dist/internal/use-collection.js.map +1 -1
  48. package/dist/list-item-factory.d.ts +10 -0
  49. package/dist/list-item-factory.d.ts.map +1 -0
  50. package/dist/list-item-factory.js +14 -0
  51. package/dist/list-item-factory.js.map +1 -0
  52. package/dist/toast.d.ts +3 -5
  53. package/dist/toast.d.ts.map +1 -1
  54. package/dist/toast.js +3 -12
  55. package/dist/toast.js.map +1 -1
  56. package/dist/types.d.ts +33 -50
  57. package/dist/types.d.ts.map +1 -1
  58. package/dist/types.js.map +1 -1
  59. package/package.json +12 -10
  60. package/src/column-view.tsx +23 -12
  61. package/src/index.ts +3 -2
  62. package/src/internal/cells.tsx +137 -20
  63. package/src/internal/collection-index.ts +8 -6
  64. package/src/internal/collection-model.ts +156 -134
  65. package/src/internal/collection.ts +28 -24
  66. package/src/internal/controlled-sync.ts +9 -12
  67. package/src/internal/drop-down.tsx +64 -60
  68. package/src/internal/expansion.ts +4 -4
  69. package/src/internal/selection.tsx +8 -8
  70. package/src/internal/tree-expansion.ts +2 -14
  71. package/src/internal/tree-order.ts +33 -121
  72. package/src/internal/use-collection.tsx +29 -8
  73. package/src/list-item-factory.tsx +27 -0
  74. package/src/toast.tsx +4 -18
  75. package/src/types.ts +35 -51
@@ -1,15 +1,15 @@
1
1
  import * as Gio from "@gtkx/gi/gio";
2
2
  import * as GObject from "@gtkx/gi/gobject";
3
3
  import * as Gtk from "@gtkx/gi/gtk";
4
+ import { createElementComponent } from "@gtkx/react";
4
5
  import { registerClass } from "@gtkx/runtime";
5
6
  import { createCollectionIndex } from "./collection-index.js";
6
7
  import { encodePart } from "./keys.js";
7
8
  import { adoptIndex, createTreeExpansion, pruneSlots } from "./tree-expansion.js";
8
9
  const STORE_CLASS_KEY = Symbol.for("gtkx.components.lazy-level-store");
10
+ const ROOT_CLASS_KEY = Symbol.for("gtkx.components.collection-root-store");
9
11
  const SLOTS_KEY = Symbol.for("gtkx.components.lazy-level-store.slots");
10
- const EMPTY_INDEX = createCollectionIndex(undefined, undefined, true);
11
- const SLOTS = sharedSlots();
12
- const newRootStore = () => new Gio.ListStore({ itemType: GObject.TYPE_OBJECT });
12
+ const EMPTY_INDEX = createCollectionIndex(undefined, [], true);
13
13
  function sharedSlots() {
14
14
  const cached = Reflect.get(globalThis, SLOTS_KEY);
15
15
  if (cached instanceof WeakMap) {
@@ -28,12 +28,21 @@ function registeredStoreClass() {
28
28
  Reflect.set(globalThis, STORE_CLASS_KEY, LazyLevelStore);
29
29
  return LazyLevelStore;
30
30
  }
31
+ function registeredRootClass() {
32
+ const cached = Reflect.get(globalThis, ROOT_CLASS_KEY);
33
+ if (typeof cached === "function") {
34
+ return cached;
35
+ }
36
+ registerClass(CollectionRootStore, { typeName: "GtkxCollectionRootStore", implements: [Gio.ListModel] });
37
+ Reflect.set(globalThis, ROOT_CLASS_KEY, CollectionRootStore);
38
+ return CollectionRootStore;
39
+ }
31
40
  function slotRefFor(value) {
32
41
  const item = value instanceof Gtk.TreeListRow ? value.getItem() : value;
33
42
  if (item === null) {
34
43
  return null;
35
44
  }
36
- const ref = SLOTS.get(item);
45
+ const ref = sharedSlots().get(item);
37
46
  return ref === undefined || ref.slot === -1 ? null : ref;
38
47
  }
39
48
  function slotPathAt(store, slot) {
@@ -112,30 +121,7 @@ function emitFlips(store, flipped) {
112
121
  store.itemsChanged(run.start, run.length, run.length);
113
122
  }
114
123
  }
115
- function childSync(context, store, slot, flipped) {
116
- const child = store.childStores.get(slot) ?? null;
117
- if (child === null || flipped.has(slot)) {
118
- return undefined;
119
- }
120
- const level = context.index.childLevel(store.level, slot);
121
- return level === undefined ? undefined : { store: child, level };
122
- }
123
- function childSyncs(context, store, overlap, flipped) {
124
- const syncs = [];
125
- const slots = store.childStores.keys().toArray().toSorted((left, right) => left - right);
126
- for (const slot of slots) {
127
- if (slot >= overlap) {
128
- continue;
129
- }
130
- const sync = childSync(context, store, slot, flipped);
131
- if (sync !== undefined) {
132
- syncs.push(sync);
133
- }
134
- }
135
- return syncs;
136
- }
137
- function syncEntry(context, entry) {
138
- const { store, level } = entry;
124
+ function syncLevel(context, store, level) {
139
125
  const previous = store.level;
140
126
  const previousLength = previous.items.length;
141
127
  const overlap = Math.min(previousLength, level.items.length);
@@ -145,14 +131,13 @@ function syncEntry(context, entry) {
145
131
  shrinkStore(context, store, previousLength, level.items.length);
146
132
  emitTailSplice(store, previousLength, level.items.length);
147
133
  emitFlips(store, flipped);
148
- return childSyncs(context, store, overlap, flipped);
149
- }
150
- function syncLevel(context, store, level) {
151
- const pending = [{ store, level }];
152
- while (pending.length > 0) {
153
- const entry = pending.pop();
154
- if (entry !== undefined) {
155
- pending.push(...syncEntry(context, entry).toReversed());
134
+ for (const [slot, child] of store.childStores) {
135
+ if (slot >= overlap || flipped.has(slot)) {
136
+ continue;
137
+ }
138
+ const childLevel = context.index.childLevel(level, slot);
139
+ if (childLevel !== undefined) {
140
+ syncLevel(context, child, childLevel);
156
141
  }
157
142
  }
158
143
  }
@@ -177,106 +162,140 @@ function childStoreFor(state, object) {
177
162
  return ensureChildStore(state.index, ref.store, ref.slot);
178
163
  }
179
164
  function treeFor(state, store) {
180
- return (state.trees.get(store) ?? Gtk.TreeListModel.new(store, false, false, (object) => childStoreFor(state, object)));
181
- }
182
- function nextTrees(state, index) {
183
- if (!index.isTree) {
184
- return new Map();
165
+ const existing = state.trees.get(store);
166
+ if (existing !== undefined) {
167
+ return existing;
185
168
  }
186
- return new Map(state.groupStores.map((store) => [store, treeFor(state, store)]));
169
+ const created = Gtk.TreeListModel.new(store, false, false, (object) => childStoreFor(state, object));
170
+ state.trees.set(store, created);
171
+ return created;
187
172
  }
188
- function pruneRebuiltLevels(state, next) {
189
- const stores = new Set([...state.trees.keys(), ...next.keys()]);
190
- for (const store of stores) {
191
- if (state.trees.get(store) !== next.get(store)) {
173
+ function rowAt(state, position) {
174
+ const item = state.model?.getItem(position);
175
+ return item instanceof Gtk.TreeListRow ? item : null;
176
+ }
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) {
192
182
  pruneSlots(state.expansion, store.level.path, () => true);
183
+ state.trees.delete(store);
193
184
  }
194
- }
195
- }
196
- function adoptTrees(state, index) {
197
- const next = nextTrees(state, index);
198
- pruneRebuiltLevels(state, next);
199
- state.trees = next;
200
- state.treeModels = next.values().toArray();
201
- }
202
- function desiredRootModels(state, index) {
203
- adoptTrees(state, index);
204
- return index.isTree ? [...state.treeModels] : [...state.groupStores];
205
- }
206
- function rowAt(state, position) {
207
- let offset = position;
208
- for (const tree of state.treeModels) {
209
- const count = tree.getNItems();
210
- if (offset < count) {
211
- return tree.getRow(offset);
185
+ if (isRemoved) {
186
+ state.groupStores.delete(group);
212
187
  }
213
- offset -= count;
214
188
  }
215
- return null;
216
- }
217
- function hasSameModels(previous, next) {
218
- return previous.length === next.length && next.every((model, index) => previous[index] === model);
219
189
  }
220
- function syncRoot(state, index) {
221
- const next = desiredRootModels(state, index);
222
- if (hasSameModels(state.rootModels, next)) {
190
+ function syncRoot(state, previous) {
191
+ const before = previous.groups.length;
192
+ const after = state.index.groups.length;
193
+ if (previous.isTree !== state.index.isTree) {
194
+ state.root?.itemsChanged(0, before, after);
223
195
  return;
224
196
  }
225
- state.root.splice(0, state.rootModels.length, next);
226
- state.rootModels = next;
227
- }
228
- function adjustGroupStores(state, context) {
229
- const { groups } = context.index;
230
- state.groupStores.length = Math.min(state.groupStores.length, groups.length);
231
- for (const level of groups.slice(state.groupStores.length)) {
232
- state.groupStores.push(newLevelStore(level));
197
+ if (before !== after) {
198
+ const start = Math.min(before, after);
199
+ state.root?.itemsChanged(start, before - start, after - start);
233
200
  }
234
201
  }
235
- function stepGroupStores(state, context, surviving) {
236
- for (const [group, level] of context.index.groups.entries()) {
237
- const store = state.groupStores[group];
238
- if (store !== undefined && group < surviving) {
202
+ function stepGroupStores(state, context) {
203
+ for (const [group, store] of state.groupStores) {
204
+ const level = context.index.groups[group];
205
+ if (level !== undefined && store.level !== level) {
239
206
  syncLevel(context, store, level);
240
207
  }
241
208
  }
242
209
  }
243
210
  function syncModel(state, index) {
211
+ if (state.root === null) {
212
+ return;
213
+ }
244
214
  const context = { index, expansion: state.expansion };
245
- const surviving = Math.min(state.groupStores.length, index.groups.length);
215
+ const previous = state.index;
246
216
  state.index = index;
247
217
  state.expansion.isSyncing = true;
248
218
  try {
249
- adjustGroupStores(state, context);
250
- syncRoot(state, index);
251
- stepGroupStores(state, context, surviving);
219
+ pruneGroups(state, previous);
220
+ syncRoot(state, previous);
221
+ stepGroupStores(state, context);
252
222
  }
253
223
  finally {
254
224
  state.expansion.isSyncing = false;
255
225
  }
256
226
  adoptIndex(state.expansion, index);
257
227
  }
228
+ function clearModel(state) {
229
+ const root = state.root;
230
+ const previousLength = state.index.groups.length;
231
+ state.expansion.isSyncing = true;
232
+ try {
233
+ if (root !== null) {
234
+ root.state = null;
235
+ }
236
+ state.root = null;
237
+ state.model = null;
238
+ state.index = EMPTY_INDEX;
239
+ state.groupStores.clear();
240
+ state.trees.clear();
241
+ state.expansion.expanded.clear();
242
+ state.expansion.slots.clear();
243
+ adoptIndex(state.expansion, EMPTY_INDEX);
244
+ if (previousLength > 0) {
245
+ root?.itemsChanged(0, previousLength, 0);
246
+ }
247
+ }
248
+ finally {
249
+ state.expansion.isSyncing = false;
250
+ }
251
+ }
258
252
  function createCollectionModel() {
259
- registeredStoreClass();
260
- const root = newRootStore();
261
253
  const state = {
262
- root,
263
- rootModels: [],
264
- model: Gtk.FlattenListModel.new(root),
265
- groupStores: [],
254
+ root: null,
255
+ model: null,
256
+ groupStores: new Map(),
266
257
  trees: new Map(),
267
- treeModels: [],
268
258
  expansion: createTreeExpansion(EMPTY_INDEX),
269
259
  index: EMPTY_INDEX,
270
260
  };
271
261
  return {
272
- model: state.model,
273
262
  expansion: state.expansion,
274
263
  rowAt: (position) => rowAt(state, position),
264
+ bind: (root, model) => {
265
+ root.state = state;
266
+ state.root = root;
267
+ state.model = model;
268
+ },
269
+ clear: () => {
270
+ clearModel(state);
271
+ },
275
272
  sync: (index) => {
276
273
  syncModel(state, index);
277
274
  },
278
275
  };
279
276
  }
277
+ class CollectionRootStore extends GObject.Object {
278
+ state = null;
279
+ vfuncGetItemType() {
280
+ return GObject.TYPE_OBJECT;
281
+ }
282
+ vfuncGetNItems() {
283
+ return this.state?.index.groups.length ?? 0;
284
+ }
285
+ vfuncGetItem(position) {
286
+ const state = this.state;
287
+ const level = state?.index.groups[position];
288
+ if (state === null || level === undefined) {
289
+ return null;
290
+ }
291
+ let store = state.groupStores.get(position);
292
+ if (store === undefined) {
293
+ store = newLevelStore(level);
294
+ state.groupStores.set(position, store);
295
+ }
296
+ return state.index.isTree ? treeFor(state, store) : store;
297
+ }
298
+ }
280
299
  class LazyLevelStore extends GObject.Object {
281
300
  level = { path: "", items: [], expandableFlags: [] };
282
301
  refs = new Map();
@@ -287,7 +306,7 @@ class LazyLevelStore extends GObject.Object {
287
306
  const created = Gtk.StringObject.new("");
288
307
  this.refs.set(position, ref);
289
308
  this.objects.set(position, created);
290
- SLOTS.set(created, ref);
309
+ sharedSlots().set(created, ref);
291
310
  return created;
292
311
  }
293
312
  vfuncGetItemType() {
@@ -303,5 +322,6 @@ class LazyLevelStore extends GObject.Object {
303
322
  return this.objects.get(position) ?? this.createItem(position);
304
323
  }
305
324
  }
306
- export { createCollectionModel, slotPathAt, slotRefFor };
325
+ const CollectionRoot = createElementComponent("GtkxCollectionRootStore", registeredRootClass());
326
+ export { CollectionRoot, createCollectionModel, slotPathAt, slotRefFor, };
307
327
  //# 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 * as Gio from \"@gtkx/gi/gio\";\nimport * as GObject from \"@gtkx/gi/gobject\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\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 LevelSync = {\n store: LevelStore;\n level: Level;\n};\n\ntype ModelState = {\n root: Gio.ListStore;\n rootModels: GObject.Object[];\n model: Gtk.FlattenListModel;\n groupStores: LevelStore[];\n trees: Map<LevelStore, Gtk.TreeListModel>;\n treeModels: Gtk.TreeListModel[];\n expansion: TreeExpansion;\n index: CollectionIndex;\n};\n\ntype CollectionModel = {\n model: Gtk.FlattenListModel;\n expansion: TreeExpansion;\n rowAt: (position: number) => Gtk.TreeListRow | null;\n sync: (index: CollectionIndex) => void;\n};\n\nconst STORE_CLASS_KEY = Symbol.for(\"gtkx.components.lazy-level-store\");\nconst SLOTS_KEY = Symbol.for(\"gtkx.components.lazy-level-store.slots\");\nconst EMPTY_INDEX = createCollectionIndex(undefined, undefined, true);\nconst SLOTS = sharedSlots();\n\nconst newRootStore = (): Gio.ListStore => new Gio.ListStore({ itemType: GObject.TYPE_OBJECT });\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 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 = SLOTS.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 childSync(\n context: SyncContext,\n store: LevelStore,\n slot: number,\n flipped: Set<number>,\n): LevelSync | undefined {\n const child = store.childStores.get(slot) ?? null;\n\n if (child === null || flipped.has(slot)) {\n return undefined;\n }\n\n const level = context.index.childLevel(store.level, slot);\n\n return level === undefined ? undefined : { store: child, level };\n}\n\nfunction childSyncs(context: SyncContext, store: LevelStore, overlap: number, flipped: Set<number>): LevelSync[] {\n const syncs: LevelSync[] = [];\n const slots = store.childStores.keys().toArray().toSorted((left, right) => left - right);\n\n for (const slot of slots) {\n if (slot >= overlap) {\n continue;\n }\n\n const sync = childSync(context, store, slot, flipped);\n\n if (sync !== undefined) {\n syncs.push(sync);\n }\n }\n\n return syncs;\n}\n\nfunction syncEntry(context: SyncContext, entry: LevelSync): LevelSync[] {\n const { store, level } = entry;\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 return childSyncs(context, store, overlap, flipped);\n}\n\nfunction syncLevel(context: SyncContext, store: LevelStore, level: Level): void {\n const pending: LevelSync[] = [{ store, level }];\n\n while (pending.length > 0) {\n const entry = pending.pop();\n\n if (entry !== undefined) {\n pending.push(...syncEntry(context, entry).toReversed());\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 return (\n state.trees.get(store) ?? Gtk.TreeListModel.new(store, false, false, (object) => childStoreFor(state, object))\n );\n}\n\nfunction nextTrees(state: ModelState, index: CollectionIndex): Map<LevelStore, Gtk.TreeListModel> {\n if (!index.isTree) {\n return new Map();\n }\n\n return new Map(state.groupStores.map((store) => [store, treeFor(state, store)]));\n}\n\nfunction pruneRebuiltLevels(state: ModelState, next: Map<LevelStore, Gtk.TreeListModel>): void {\n const stores: Set<LevelStore> = new Set([...state.trees.keys(), ...next.keys()]);\n\n for (const store of stores) {\n if (state.trees.get(store) !== next.get(store)) {\n pruneSlots(state.expansion, store.level.path, () => true);\n }\n }\n}\n\nfunction adoptTrees(state: ModelState, index: CollectionIndex): void {\n const next = nextTrees(state, index);\n pruneRebuiltLevels(state, next);\n state.trees = next;\n state.treeModels = next.values().toArray();\n}\n\nfunction desiredRootModels(state: ModelState, index: CollectionIndex): GObject.Object[] {\n adoptTrees(state, index);\n\n return index.isTree ? [...state.treeModels] : [...state.groupStores];\n}\n\nfunction rowAt(state: ModelState, position: number): Gtk.TreeListRow | null {\n let offset = position;\n\n for (const tree of state.treeModels) {\n const count = tree.getNItems();\n\n if (offset < count) {\n return tree.getRow(offset);\n }\n\n offset -= count;\n }\n\n return null;\n}\n\nfunction hasSameModels(previous: GObject.Object[], next: GObject.Object[]): boolean {\n return previous.length === next.length && next.every((model, index) => previous[index] === model);\n}\n\nfunction syncRoot(state: ModelState, index: CollectionIndex): void {\n const next = desiredRootModels(state, index);\n\n if (hasSameModels(state.rootModels, next)) {\n return;\n }\n\n state.root.splice(0, state.rootModels.length, next);\n state.rootModels = next;\n}\n\nfunction adjustGroupStores(state: ModelState, context: SyncContext): void {\n const { groups } = context.index;\n state.groupStores.length = Math.min(state.groupStores.length, groups.length);\n\n for (const level of groups.slice(state.groupStores.length)) {\n state.groupStores.push(newLevelStore(level));\n }\n}\n\nfunction stepGroupStores(state: ModelState, context: SyncContext, surviving: number): void {\n for (const [group, level] of context.index.groups.entries()) {\n const store = state.groupStores[group];\n\n if (store !== undefined && group < surviving) {\n syncLevel(context, store, level);\n }\n }\n}\n\nfunction syncModel(state: ModelState, index: CollectionIndex): void {\n const context: SyncContext = { index, expansion: state.expansion };\n const surviving = Math.min(state.groupStores.length, index.groups.length);\n state.index = index;\n state.expansion.isSyncing = true;\n\n try {\n adjustGroupStores(state, context);\n syncRoot(state, index);\n stepGroupStores(state, context, surviving);\n } finally {\n state.expansion.isSyncing = false;\n }\n\n adoptIndex(state.expansion, index);\n}\n\nfunction createCollectionModel(): CollectionModel {\n registeredStoreClass();\n const root = newRootStore();\n\n const state: ModelState = {\n root,\n rootModels: [],\n model: Gtk.FlattenListModel.new(root),\n groupStores: [],\n trees: new Map(),\n treeModels: [],\n expansion: createTreeExpansion(EMPTY_INDEX),\n index: EMPTY_INDEX,\n };\n\n return {\n model: state.model,\n expansion: state.expansion,\n rowAt: (position) => rowAt(state, position),\n sync: (index) => {\n syncModel(state, index);\n },\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 SLOTS.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\nexport { createCollectionModel, slotPathAt, slotRefFor, type CollectionModel, type SlotRef };\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 { 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,11 +1,12 @@
1
+ import type * as Gtk from "@gtkx/gi/gtk";
1
2
  import type { ListItem } from "../types.js";
2
- import type { CollectionIndex } from "./collection-index.js";
3
+ import type { CollectionIndex, SectionIdentity } from "./collection-index.js";
3
4
  import type { CollectionModel, SlotRef } from "./collection-model.js";
4
5
  import type { MatchedRows } from "./tree-order.js";
5
- type Collection = Pick<CollectionModel, "model" | "expansion" | "rowAt"> & {
6
+ type Collection = Pick<CollectionModel, "expansion" | "rowAt"> & {
6
7
  isTree: boolean;
7
8
  itemAt: (ref: SlotRef) => ListItem | undefined;
8
- sectionFor: (levelPath: string) => unknown;
9
+ sectionFor: (levelPath: string) => SectionIdentity | undefined;
9
10
  idAt: (position: number) => string | null;
10
11
  idsAt: (positions: number[]) => string[];
11
12
  pathAt: (position: number) => string | null;
@@ -13,6 +14,6 @@ type Collection = Pick<CollectionModel, "model" | "expansion" | "rowAt"> & {
13
14
  rowsFor: (ids: string[]) => MatchedRows;
14
15
  };
15
16
  declare function isCollectionIdle(collection: Collection): boolean;
16
- declare function createCollection(collectionModel: CollectionModel, index: CollectionIndex): Collection;
17
+ declare function createCollection(gtkModel: CollectionModel, index: CollectionIndex, model: Gtk.FlattenListModel | null): Collection;
17
18
  export { createCollection, isCollectionIdle, type Collection };
18
19
  //# sourceMappingURL=collection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/internal/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,KAAK,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC,GAAG;IACvE,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC1C,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACzC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,WAAW,CAAC;CAC3C,CAAC;AA2DF,iBAAS,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAIzD;AAED,iBAAS,gBAAgB,CAAC,eAAe,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,UAAU,CAc9F;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/internal/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,KAAK,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,eAAe,GAAG,SAAS,CAAC;IAC/D,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC1C,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACzC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,WAAW,CAAC;CAC3C,CAAC;AA2DF,iBAAS,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAIzD;AAED,iBAAS,gBAAgB,CACrB,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,GAAG,CAAC,gBAAgB,GAAG,IAAI,GACnC,UAAU,CAaZ;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,CAAC"}
@@ -2,61 +2,60 @@ import { slotPathAt, slotRefFor } from "./collection-model.js";
2
2
  import { findIds, findRows } from "./tree-order.js";
3
3
  const NO_ROWS = { positions: [], ids: [] };
4
4
  const NO_IDS = [];
5
- function rowsFor(collectionModel, ids) {
5
+ function rowsFor(gtkModel, ids) {
6
6
  if (ids.length === 0) {
7
7
  return NO_ROWS;
8
8
  }
9
- const { expansion } = collectionModel;
9
+ const { expansion } = gtkModel;
10
10
  return findRows(expansion.index, expansion.slots, new Set(ids));
11
11
  }
12
- function positionFor(collectionModel, id) {
13
- const [first = -1] = rowsFor(collectionModel, [id]).positions;
12
+ function positionFor(gtkModel, id) {
13
+ const [first = -1] = rowsFor(gtkModel, [id]).positions;
14
14
  return first;
15
15
  }
16
- function refAt(collectionModel, position) {
16
+ function refAt(model, position) {
17
17
  if (position < 0) {
18
18
  return null;
19
19
  }
20
- return slotRefFor(collectionModel.model.getItem(position));
20
+ return slotRefFor(model?.getItem(position) ?? null);
21
21
  }
22
22
  function itemAt(index, ref) {
23
23
  return index.itemAt(ref.store.level.path, ref.slot);
24
24
  }
25
- function idAt(collectionModel, index, position) {
26
- const ref = refAt(collectionModel, position);
25
+ function idAt(model, index, position) {
26
+ const ref = refAt(model, position);
27
27
  return ref === null ? null : (itemAt(index, ref)?.id ?? null);
28
28
  }
29
- function pathAt(collectionModel, position) {
30
- const ref = refAt(collectionModel, position);
29
+ function pathAt(model, position) {
30
+ const ref = refAt(model, position);
31
31
  if (ref === null) {
32
32
  return null;
33
33
  }
34
34
  return slotPathAt(ref.store, ref.slot);
35
35
  }
36
- function idsAt(collectionModel, positions) {
36
+ function idsAt(gtkModel, positions) {
37
37
  if (positions.length === 0) {
38
38
  return NO_IDS;
39
39
  }
40
- const { expansion } = collectionModel;
40
+ const { expansion } = gtkModel;
41
41
  return findIds(expansion.index, expansion.slots, new Set(positions));
42
42
  }
43
43
  function isCollectionIdle(collection) {
44
44
  const { expansion } = collection;
45
45
  return !expansion.isApplying && !expansion.isSyncing;
46
46
  }
47
- function createCollection(collectionModel, index) {
47
+ function createCollection(gtkModel, index, model) {
48
48
  return {
49
- model: collectionModel.model,
50
- expansion: collectionModel.expansion,
49
+ expansion: gtkModel.expansion,
51
50
  isTree: index.isTree,
52
- rowAt: collectionModel.rowAt,
51
+ rowAt: gtkModel.rowAt,
53
52
  itemAt: (ref) => itemAt(index, ref),
54
53
  sectionFor: index.sectionFor,
55
- idAt: (position) => idAt(collectionModel, index, position),
56
- idsAt: (positions) => idsAt(collectionModel, positions),
57
- pathAt: (position) => pathAt(collectionModel, position),
58
- positionFor: (id) => positionFor(collectionModel, id),
59
- rowsFor: (ids) => rowsFor(collectionModel, ids),
54
+ idAt: (position) => idAt(model, index, position),
55
+ idsAt: (positions) => idsAt(gtkModel, positions),
56
+ pathAt: (position) => pathAt(model, position),
57
+ positionFor: (id) => positionFor(gtkModel, id),
58
+ rowsFor: (ids) => rowsFor(gtkModel, ids),
60
59
  };
61
60
  }
62
61
  export { createCollection, isCollectionIdle };
@@ -1 +1 @@
1
- {"version":3,"file":"collection.js","sourceRoot":"","sources":["../../src/internal/collection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ListItem } from \"../types.js\";\nimport type { CollectionIndex } from \"./collection-index.js\";\nimport type { CollectionModel, SlotRef } from \"./collection-model.js\";\nimport type { MatchedRows } from \"./tree-order.js\";\nimport { slotPathAt, slotRefFor } from \"./collection-model.js\";\nimport { findIds, findRows } from \"./tree-order.js\";\n\ntype Collection = Pick<CollectionModel, \"model\" | \"expansion\" | \"rowAt\"> & {\n isTree: boolean;\n itemAt: (ref: SlotRef) => ListItem | undefined;\n sectionFor: (levelPath: string) => unknown;\n idAt: (position: number) => string | null;\n idsAt: (positions: number[]) => string[];\n pathAt: (position: number) => string | null;\n positionFor: (id: string) => number;\n rowsFor: (ids: string[]) => MatchedRows;\n};\n\nconst NO_ROWS: MatchedRows = { positions: [], ids: [] };\nconst NO_IDS: string[] = [];\n\nfunction rowsFor(collectionModel: CollectionModel, ids: string[]): MatchedRows {\n if (ids.length === 0) {\n return NO_ROWS;\n }\n\n const { expansion } = collectionModel;\n\n return findRows(expansion.index, expansion.slots, new Set(ids));\n}\n\nfunction positionFor(collectionModel: CollectionModel, id: string): number {\n const [first = -1] = rowsFor(collectionModel, [id]).positions;\n\n return first;\n}\n\nfunction refAt(collectionModel: CollectionModel, position: number): SlotRef | null {\n if (position < 0) {\n return null;\n }\n\n return slotRefFor(collectionModel.model.getItem(position));\n}\n\nfunction itemAt(index: CollectionIndex, ref: SlotRef): ListItem | undefined {\n return index.itemAt(ref.store.level.path, ref.slot);\n}\n\nfunction idAt(collectionModel: CollectionModel, index: CollectionIndex, position: number): string | null {\n const ref = refAt(collectionModel, position);\n\n return ref === null ? null : (itemAt(index, ref)?.id ?? null);\n}\n\nfunction pathAt(collectionModel: CollectionModel, position: number): string | null {\n const ref = refAt(collectionModel, position);\n\n if (ref === null) {\n return null;\n }\n\n return slotPathAt(ref.store, ref.slot);\n}\n\nfunction idsAt(collectionModel: CollectionModel, positions: number[]): string[] {\n if (positions.length === 0) {\n return NO_IDS;\n }\n\n const { expansion } = collectionModel;\n\n return findIds(expansion.index, expansion.slots, new Set(positions));\n}\n\nfunction isCollectionIdle(collection: Collection): boolean {\n const { expansion } = collection;\n\n return !expansion.isApplying && !expansion.isSyncing;\n}\n\nfunction createCollection(collectionModel: CollectionModel, index: CollectionIndex): Collection {\n return {\n model: collectionModel.model,\n expansion: collectionModel.expansion,\n isTree: index.isTree,\n rowAt: collectionModel.rowAt,\n itemAt: (ref) => itemAt(index, ref),\n sectionFor: index.sectionFor,\n idAt: (position) => idAt(collectionModel, index, position),\n idsAt: (positions) => idsAt(collectionModel, positions),\n pathAt: (position) => pathAt(collectionModel, position),\n positionFor: (id) => positionFor(collectionModel, id),\n rowsFor: (ids) => rowsFor(collectionModel, ids),\n };\n}\n\nexport { createCollection, isCollectionIdle, type Collection };\n"]}
1
+ {"version":3,"file":"collection.js","sourceRoot":"","sources":["../../src/internal/collection.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAapD,MAAM,OAAO,GAAgB,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AACxD,MAAM,MAAM,GAAa,EAAE,CAAC;AAE5B,SAAS,OAAO,CAAC,QAAyB,EAAE,GAAa;IACrD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAE/B,OAAO,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,WAAW,CAAC,QAAyB,EAAE,EAAU;IACtD,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEvD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,KAAK,CAAC,KAAkC,EAAE,QAAgB;IAC/D,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,MAAM,CAAC,KAAsB,EAAE,GAAY;IAChD,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,IAAI,CAAC,KAAkC,EAAE,KAAsB,EAAE,QAAgB;IACtF,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAEnC,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,MAAM,CAAC,KAAkC,EAAE,QAAgB;IAChE,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAEnC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,KAAK,CAAC,QAAyB,EAAE,SAAmB;IACzD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAE/B,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,gBAAgB,CAAC,UAAsB;IAC5C,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;IAEjC,OAAO,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;AACzD,CAAC;AAED,SAAS,gBAAgB,CACrB,QAAyB,EACzB,KAAsB,EACtB,KAAkC;IAElC,OAAO;QACH,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC;QACnC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC;QAChD,KAAK,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC;QAChD,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC;QAC7C,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;KAC3C,CAAC;AACN,CAAC;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAmB,CAAC","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { ListItem } from \"../types.js\";\nimport type { CollectionIndex, SectionIdentity } from \"./collection-index.js\";\nimport type { CollectionModel, SlotRef } from \"./collection-model.js\";\nimport type { MatchedRows } from \"./tree-order.js\";\nimport { slotPathAt, slotRefFor } from \"./collection-model.js\";\nimport { findIds, findRows } from \"./tree-order.js\";\n\ntype Collection = Pick<CollectionModel, \"expansion\" | \"rowAt\"> & {\n isTree: boolean;\n itemAt: (ref: SlotRef) => ListItem | undefined;\n sectionFor: (levelPath: string) => SectionIdentity | undefined;\n idAt: (position: number) => string | null;\n idsAt: (positions: number[]) => string[];\n pathAt: (position: number) => string | null;\n positionFor: (id: string) => number;\n rowsFor: (ids: string[]) => MatchedRows;\n};\n\nconst NO_ROWS: MatchedRows = { positions: [], ids: [] };\nconst NO_IDS: string[] = [];\n\nfunction rowsFor(gtkModel: CollectionModel, ids: string[]): MatchedRows {\n if (ids.length === 0) {\n return NO_ROWS;\n }\n\n const { expansion } = gtkModel;\n\n return findRows(expansion.index, expansion.slots, new Set(ids));\n}\n\nfunction positionFor(gtkModel: CollectionModel, id: string): number {\n const [first = -1] = rowsFor(gtkModel, [id]).positions;\n\n return first;\n}\n\nfunction refAt(model: Gtk.FlattenListModel | null, position: number): SlotRef | null {\n if (position < 0) {\n return null;\n }\n\n return slotRefFor(model?.getItem(position) ?? null);\n}\n\nfunction itemAt(index: CollectionIndex, ref: SlotRef): ListItem | undefined {\n return index.itemAt(ref.store.level.path, ref.slot);\n}\n\nfunction idAt(model: Gtk.FlattenListModel | null, index: CollectionIndex, position: number): string | null {\n const ref = refAt(model, position);\n\n return ref === null ? null : (itemAt(index, ref)?.id ?? null);\n}\n\nfunction pathAt(model: Gtk.FlattenListModel | null, position: number): string | null {\n const ref = refAt(model, position);\n\n if (ref === null) {\n return null;\n }\n\n return slotPathAt(ref.store, ref.slot);\n}\n\nfunction idsAt(gtkModel: CollectionModel, positions: number[]): string[] {\n if (positions.length === 0) {\n return NO_IDS;\n }\n\n const { expansion } = gtkModel;\n\n return findIds(expansion.index, expansion.slots, new Set(positions));\n}\n\nfunction isCollectionIdle(collection: Collection): boolean {\n const { expansion } = collection;\n\n return !expansion.isApplying && !expansion.isSyncing;\n}\n\nfunction createCollection(\n gtkModel: CollectionModel,\n index: CollectionIndex,\n model: Gtk.FlattenListModel | null,\n): Collection {\n return {\n expansion: gtkModel.expansion,\n isTree: index.isTree,\n rowAt: gtkModel.rowAt,\n itemAt: (ref) => itemAt(index, ref),\n sectionFor: index.sectionFor,\n idAt: (position) => idAt(model, index, position),\n idsAt: (positions) => idsAt(gtkModel, positions),\n pathAt: (position) => pathAt(model, position),\n positionFor: (id) => positionFor(gtkModel, id),\n rowsFor: (ids) => rowsFor(gtkModel, ids),\n };\n}\n\nexport { createCollection, isCollectionIdle, type Collection };\n"]}
@@ -1,11 +1,9 @@
1
- import type { Collection } from "./collection.js";
2
- type ControlledIds = string[] | null | undefined;
3
- type ControlledSyncOptions = {
4
- ids: ControlledIds;
5
- collection: Collection;
6
- widget?: object | null | undefined;
7
- apply: (ids: ControlledIds) => void;
1
+ type ControlledSyncOptions<T> = {
2
+ value: T;
3
+ source?: object | null | undefined;
4
+ target?: object | null | undefined;
5
+ apply: (value: T) => void;
8
6
  };
9
- declare function useControlledSync(options: ControlledSyncOptions): () => void;
7
+ declare function useControlledSync<T>(options: ControlledSyncOptions<T>): () => void;
10
8
  export { useControlledSync };
11
9
  //# sourceMappingURL=controlled-sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"controlled-sync.d.ts","sourceRoot":"","sources":["../../src/internal/controlled-sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,KAAK,aAAa,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AAEjD,KAAK,qBAAqB,GAAG;IACzB,GAAG,EAAE,aAAa,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,KAAK,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,iBAAS,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAiBrE;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"controlled-sync.d.ts","sourceRoot":"","sources":["../../src/internal/controlled-sync.ts"],"names":[],"mappings":"AAGA,KAAK,qBAAqB,CAAC,CAAC,IAAI;IAC5B,KAAK,EAAE,CAAC,CAAC;IACT,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC7B,CAAC;AAEF,iBAAS,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAiB3E;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { useLatestRef } from "@gtkx/react/internal";
2
2
  import { startTransition, useLayoutEffect, useState } from "react";
3
3
  function useControlledSync(options) {
4
- const { ids, collection, widget } = options;
4
+ const { value, source, target } = options;
5
5
  const [drift, setDrift] = useState(0);
6
6
  const markDrift = () => {
7
7
  startTransition(() => {
@@ -10,8 +10,8 @@ function useControlledSync(options) {
10
10
  };
11
11
  const applyRef = useLatestRef(options.apply);
12
12
  useLayoutEffect(() => {
13
- applyRef.current(ids);
14
- }, [applyRef, widget, collection, ids, drift]);
13
+ applyRef.current(value);
14
+ }, [applyRef, target, source, value, drift]);
15
15
  return markDrift;
16
16
  }
17
17
  export { useControlledSync };