From d1613e631f6542d5aef4d021ef8f2f253784e090 Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Thu, 14 Nov 2024 12:45:40 -0800 Subject: [PATCH] DataSync: support custom newRecordBehaviour with useQuery --- lib/IHP/DataSync/ihp-datasync.js | 4 ++-- lib/IHP/DataSync/react.js | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/IHP/DataSync/ihp-datasync.js b/lib/IHP/DataSync/ihp-datasync.js index d6c41b740..3c981fa33 100644 --- a/lib/IHP/DataSync/ihp-datasync.js +++ b/lib/IHP/DataSync/ihp-datasync.js @@ -236,7 +236,7 @@ const PREPEND_NEW_RECORD = 1; export const NewRecordBehaviour = { APPEND_NEW_RECORD, PREPEND_NEW_RECORD }; class DataSubscription { - constructor(query, cache = null) { + constructor(query, options = null, cache = null) { if (typeof query !== "object" || !('table' in query)) { throw new Error("Query passed to `new DataSubscription(..)` doesn't look like a query object. If you're using the `query()` functions to costruct the object, make sure you pass the `.query` property, like this: `new DataSubscription(query('my_table').orderBy('createdAt').query)`"); } @@ -261,7 +261,7 @@ class DataSubscription { this.onMessage = this.onMessage.bind(this); // When a new record is inserted, do we put it at the end or at the beginning? - this.newRecordBehaviour = this.detectNewRecordBehaviour(); + this.newRecordBehaviour = (options && 'newRecordBehaviour' in options) ? options.newRecordBehaviour : this.detectNewRecordBehaviour(); this.optimisticCreatedPendingRecordIds = []; } diff --git a/lib/IHP/DataSync/react.js b/lib/IHP/DataSync/react.js index d8c7c051b..ba008e110 100644 --- a/lib/IHP/DataSync/react.js +++ b/lib/IHP/DataSync/react.js @@ -12,8 +12,8 @@ const recordsCache = new Map(); * @example * const messages = useQuery(query('messages').orderBy('createdAt')); */ -export function useQuery(queryBuilder) { - const dataSubscription = DataSubscriptionStore.get(queryBuilder.query); +export function useQuery(queryBuilder, options = null) { + const dataSubscription = DataSubscriptionStore.get(queryBuilder.query, options); const isAuthCompleted = useContext(AuthCompletedContext); const records = useSyncExternalStore(dataSubscription.subscribe, dataSubscription.getRecords) @@ -73,19 +73,19 @@ export class DataSubscriptionStore { // once it has arrived. static cache = new Map(); - static get(query) { - const strinigifiedQuery = JSON.stringify(query); - const existingSubscription = DataSubscriptionStore.queryMap.get(strinigifiedQuery) + static get(query, options = null) { + const key = JSON.stringify(query) + JSON.stringify(options); + const existingSubscription = DataSubscriptionStore.queryMap.get(key) if (existingSubscription) { return existingSubscription; } else { - const subscription = new DataSubscription(query, DataSubscriptionStore.cache); + const subscription = new DataSubscription(query, options, DataSubscriptionStore.cache); subscription.createOnServer(); - subscription.onClose = () => { DataSubscriptionStore.queryMap.delete(strinigifiedQuery); }; + subscription.onClose = () => { DataSubscriptionStore.queryMap.delete(key); }; - DataSubscriptionStore.queryMap.set(strinigifiedQuery, subscription); + DataSubscriptionStore.queryMap.set(key, subscription); // If the query changes very rapid in `useQuery` it can happen that the `dataSubscription.subscribe` // is never called at all. In this case we have a unused DataSubscription laying around. We avoid