tinyplex / tinybase

The reactive data store for local‑first apps.
https://tinybase.org
MIT License
3.57k stars 69 forks source link

Support an array of sliceId for setIndexDefinition? #30

Closed tienle closed 1 year ago

tienle commented 1 year ago

Is your feature request related to a problem? Please describe. We were trying to create indexes for events object by date. So that if we look for a specific date then it will return the collection of events that cover that given date. Event { start: Date, end: Date, ...}

indexes.setIndexDefinition( 
    'eventsByDate', 
    'events',
    (getCell) =>  ['2022-09-19', '2022-09-20'] // eg. return array of ISO date from this code: eachDayOfInterval(getCell('from'), getCell('to')).map((date) => formatISO(date))
);

indexes.getSliceRowIds('eventsByDate', '2022-09-19') // return events that cover this date 
indexes.getSliceRowIds('eventsByDate', '2022-09-20')  // return events that cover this date  

Describe the solution you'd like I think if the setIndexDefinition could support having sliceId array to index rows then it's more flexible.

Describe alternatives you've considered We are not sure of the best way to solve this with Tinybase without manually indexing rows by listening to the row-adding event.

Additional context N/A

jamesgpearce commented 1 year ago

OK, and if there is a date with no events you want to access an empty array, I assume?

I can imagine something like this. OK if I think about it for a few days?

tienle commented 1 year ago

OK, and if there is a date with no events you want to access an empty array, I assume?

I guess that we can easily handle the conversion even if it returns null | undefined result for non-existing sliceId.

I can imagine something like this. OK if I think about it for a few days?

Sure, I believe this kind of proposal needs to be carefully considered.

Again, thanks for a wonderful project. We are writing an employee scheduler component and this tinybase does an amazing job to simplify things.

jamesgpearce commented 1 year ago

The main disjoint from the current behavior here is that today, every row lives in one and just one slice. Here, you can now have a row that exists in multiple slices, so we'll need to bookkeep them all.

Nevertheless, I can think of other uses for this (eg keyword search!) so I will have go.

jamesgpearce commented 1 year ago

OK, @tienle, please see the example below, which works with the new beta release.

Let me know if that works for you. You can try it out by installing v2.1.0-beta.0 from NPM.

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  rex: {species: 'dog'},
});

const indexes = createIndexes(store);
indexes.setIndexDefinition('containsLetter', 'pets', (_, rowId) =>
  rowId.split(''),
);

console.log(indexes.getSliceIds('containsLetter'));
// -> ['f', 'i', 'd', 'o', 'e', 'l', 'x', 'r']
console.log(indexes.getSliceRowIds('containsLetter', 'i'));
// -> ['fido', 'felix']
console.log(indexes.getSliceRowIds('containsLetter', 'x'));
// -> ['felix', 'rex']
jamesgpearce commented 1 year ago

Also check out https://beta.tinybase.org/demos/word-frequencies/ - I'm pretty pleased with how this worked out. Thank you for the inspiration!

tienle commented 1 year ago

@jamesgpearce Awesome. I will check it out and let you know if there is any issue.

tienle commented 1 year ago

So far, it works great. Thanks for the update @jamesgpearce 🚀

jamesgpearce commented 1 year ago

Great! Good luck with the app and I’ll close this out.

I’ll release it to GA in v2.1.

jamesgpearce commented 1 year ago

https://github.com/tinyplex/tinybase/releases/tag/v2.1.0