compendium shennanegins

CCalego10/19/2021
TIL about CompendiumContent.getDocuments taking nedb queries.
game.packs.get('dnd5e.heroes').getDocuments({ 'data.abilities.con.value': {$gt: 14} });

More info about nedb queries: https://github.com/louischatriot/nedb#finding-documents
CCalego10/19/2021
CCalego10/19/2021
The above returns all actors in the compendium with a constitution value greater than 14.
EEthaks10/19/2021
I vaguely remember Atro mentioning this on the mothership at some point, too. IIRC documents fetched by this are not cached though, which can make repeated calls a bit costly.
EEthaks10/19/2021
(Not sure if the caching situation changed in the meantime, so I cannot say whether the warning still applies)
CCalego10/19/2021
Yeah good call, the docs only mention caching for the singular getDocument
Cccjmk10/19/2021
hmm even with no caching this might be useful for my module 🤔
Cccjmk10/19/2021
i mean, its mostly working already, but half of the code is held together with ducttape and best intentions; it would probably be helpful if I use queries to say, get only Spells when I want spells, and only Classes when I want classes, and don't rely on the user doing things the proper way
Cccjmk10/19/2021
spoiler alert: they never do
CCalego10/19/2021
@ccjmk do you use the compendium indexes for your thing?
EEthaks10/19/2021
The query option is why inquired about 5e's data usage a while back, but all the custom stuff you had to do made it a bit difficult for me to recommend this
Cccjmk10/19/2021
ehhh to be honest, I .. think ? but I never understood that part deeply. Ghost helped me set up a function I could call with a compendium name, and it would get all the items on the compendium, ready to be added into an actor
Cccjmk10/19/2021
and I just parsed it after the fact as I needed
Cccjmk10/19/2021
this' Le Function
Cccjmk10/19/2021
export async function getItemListFromPackListByNames(packNames: string[]) {
  const allItems = [];
  for (const compendiumName of packNames) {
    const pack = game.packs.get(compendiumName);
    const worldItems = game.items;
    if (!worldItems) throw new Error('game.items not initialized yet');
    if (!pack) ui.notifications?.warn(`No pack for name [${compendiumName}]!`);
    if (pack?.documentName !== 'Item') throw new Error(`${compendiumName} is not an Item pack`);
    const itemPack = pack as CompendiumCollection<CompendiumCollection.Metadata & { entity: 'Item' }>;
    const itemsPromises: Promise<Item | null | undefined>[] = [];
    for (const itemIndex of pack.index.keys()) {
      const item = itemPack.getDocument(itemIndex);
      itemsPromises.push(item);
    }
    const items = await Promise.all(itemsPromises);
    allItems.push(
      ...items
        .filter((item): item is Item => !!item)
        .map((item) => {
          const itemFromCompendium = worldItems.fromCompendium(item);
          // intentionally adding the flag without using the API as I don't want to persist this flag
          // this should be enough and more lightweight
          itemFromCompendium.flags.hct = {
            link: {
              id: item.id,
              pack: item.pack,
            },
          };
          return itemFromCompendium;
        }),
    );
  }
  return allItems;
}
Cccjmk10/19/2021
given that its iterating over const itemIndex of pack.index.keys() I think the answer is "technically yes"
CCalego10/19/2021
Looks like yes but also no
CCalego10/19/2021
Lol
Cccjmk10/19/2021
Schrodinger's Indexes
CCalego10/19/2021
Have a look at the getIndex method on compendium collection
CCalego10/19/2021
It lets you build and cache a slimmed down version of a compendium's documents locally
CCalego10/19/2021
So for instance if you need to display all the spells and their levels, you can add spell level to the index
CCalego10/19/2021
Instead of parsing all spells from the compendium itself
Cccjmk10/19/2021
hmm but I will need the full item anyway later, though if getting trimmed versions of documents is performant enough, I guess I could get the minimum I need for displaying/sorting data, and search it on-demand when the user actually submits the actor to be created (which is usually just name, img, requirement, and for spells, level + I imagine index to re-find the appropriate documents)
CCalego10/19/2021
right, later you get the full items, but only the ones you actually need