diff --git a/djx/src/main/ts/store.ts b/djx/src/main/ts/store.ts --- a/djx/src/main/ts/store.ts +++ b/djx/src/main/ts/store.ts @@ -42,19 +42,32 @@ export const query = (store: Qu }; }; +/** + * Wraps the query method of the store, the resulting method takes a query + * expression and returns two observable sequences. The first sequence represents + * the results of the query, the second sequence provides the updates to the + * query results. + * + * @param store The store used to query data + * @param includeUpdates The flag to include item updates not only additions and + * deletions. By default this flag is set to true. + * @returns Two observable sequences + */ export const queryEx = (store: Queryable, includeUpdates = true) => (query?: Q, options?: O): [data: QueryResults, updates: QueryResults] => { - const pending: T[] = []; - - let results: PromiseOrValue = pending; + /** count active observers */ + let listeners = 0; + let results: PromiseOrValue = []; const data = observe>(({ next, complete, error }) => { const processResults = (items: T[]) => items.forEach((item, newIndex) => next({ item, newIndex, prevIndex: -1 })); try { - if (results === pending) + // is there are no active observers here, we need to query actual + // data from the store. + if (listeners === 0) results = store.query(query, options); if (isPromise(results)) { @@ -74,8 +87,14 @@ export const queryEx = (store: const updates = observe>(({ next, complete, error, isClosed }) => { try { if (!isClosed() && isDjObservableResults(results)) { + // subscribe fot the changes + listeners++; const h = results.observe((item, prevIndex, newIndex) => next({ item, prevIndex, newIndex }), includeUpdates); - return () => h.remove(); + return () => { + // unsubscribe from changes + listeners--; + h.remove(); + }; } else { complete(); } diff --git a/playground/build.gradle b/playground/build.gradle --- a/playground/build.gradle +++ b/playground/build.gradle @@ -56,8 +56,8 @@ tasks.matching{ it.name =~ /^configureTs } } -npmInstall { - //npmInstall.dependsOn it +task npmInstallLocalDeps { + npmInstall.dependsOn it dependsOn configurations.npmLocal doFirst {