Skip to content

Commit

Permalink
Use orbit LiveQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
tchak committed Jun 21, 2020
1 parent 6b3810a commit 0d80a0e
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 87 deletions.
50 changes: 4 additions & 46 deletions addon/-private/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import Orbit, {
import { QueryResult, QueryResultData } from '@orbit/record-cache';
import { MemoryCache } from '@orbit/memory';
import IdentityMap from '@orbit/identity-map';
import LiveQuery from './live-query';
import { destroy } from 'ember-destroyable-polyfill';

import Model from './model';
import ModelFactory from './model-factory';
import recordIdentitySerializer from './utils/record-identity-serializer';
Expand All @@ -26,29 +27,20 @@ export interface CacheSettings {
modelFactory: ModelFactory;
}

interface LiveQueryContract {
invalidate(): void;
}

export default class Cache {
private _sourceCache: MemoryCache;
private _modelFactory: ModelFactory;
private _identityMap: IdentityMap<RecordIdentity, Model> = new IdentityMap({
serializer: recordIdentitySerializer
});
private _liveQuerySet: Set<LiveQueryContract> = new Set();
private _patchListener: Listener;
private _resetListener: Listener;

constructor(settings: CacheSettings) {
this._sourceCache = settings.sourceCache;
this._modelFactory = settings.modelFactory;

this._patchListener = this.generatePatchListener();
this._resetListener = this.generateResetListener();

this._sourceCache.on('patch', this._patchListener);
this._sourceCache.on('reset', this._resetListener);
}

get keyMap(): KeyMap | undefined {
Expand Down Expand Up @@ -231,28 +223,6 @@ export default class Cache {
}
}

liveQuery(
queryOrExpressions: QueryOrExpressions,
options?: RequestOptions,
id?: string
) {
const query = buildQuery(
queryOrExpressions,
options,
id,
this._sourceCache.queryBuilder
);

const liveQuery = LiveQuery.create({
getContent: () => this.query(query),
_liveQuerySet: this._liveQuerySet
});

this._liveQuerySet.add(liveQuery);

return liveQuery;
}

find(type: string, id?: string): Model | Model[] {
if (id === undefined) {
return this.findRecords(type);
Expand Down Expand Up @@ -316,14 +286,14 @@ export default class Cache {

destroy(): void {
this._sourceCache.off('patch', this._patchListener);
this._sourceCache.off('reset', this._resetListener);

for (let record of this._identityMap.values()) {
record.disconnect();
}

destroy(this);

this._identityMap.clear();
this._liveQuerySet.clear();
}

private notifyPropertyChange(
Expand All @@ -337,20 +307,12 @@ export default class Cache {
}
}

private notifyLiveQueryChange(): void {
for (let liveQuery of this._liveQuerySet) {
liveQuery.invalidate();
}
}

private generatePatchListener(): (operation: RecordOperation) => void {
return (operation: RecordOperation) => {
const record = operation.record as Record;
const { type, id, keys, attributes, relationships } = record;
const identity = { type, id };

this.notifyLiveQueryChange();

switch (operation.op) {
case 'updateRecord':
for (let properties of [attributes, keys, relationships]) {
Expand Down Expand Up @@ -383,10 +345,6 @@ export default class Cache {
}
};
}

private generateResetListener(): () => void {
return () => this.notifyLiveQueryChange();
}
}

function isQueryResultData(
Expand Down
8 changes: 0 additions & 8 deletions addon/-private/factories/memory-source-factory.js

This file was deleted.

11 changes: 11 additions & 0 deletions addon/-private/factories/memory-source-factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import MemorySource, { MemorySourceSettings } from '@orbit/memory';

export default {
create(injections: MemorySourceSettings = {}) {
injections.name = injections.name || 'store';
// injections.cacheSettings = {
// debounceLiveQueries: false
// };
return new MemorySource(injections);
}
};
2 changes: 1 addition & 1 deletion addon/-private/fields/attr.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { tracked } from '@glimmer/tracking';
import { tracked } from './tracking';
import { Dict } from '@orbit/utils';

import Model from '../model';
Expand Down
2 changes: 1 addition & 1 deletion addon/-private/fields/has-many.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { tracked } from '@glimmer/tracking';
import { tracked } from './tracking';
import { RelationshipDefinition } from '@orbit/data';

import Model from '../model';
Expand Down
2 changes: 1 addition & 1 deletion addon/-private/fields/has-one.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { tracked } from '@glimmer/tracking';
import { tracked } from './tracking';
import { RelationshipDefinition } from '@orbit/data';

import Model from '../model';
Expand Down
2 changes: 1 addition & 1 deletion addon/-private/fields/key.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { tracked } from '@glimmer/tracking';
import { tracked } from './tracking';
import { Dict } from '@orbit/utils';

import Model from '../model';
Expand Down
9 changes: 9 additions & 0 deletions addon/-private/fields/tracking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { tracked as trackedFn } from '@glimmer/tracking';

type trackedWithPropertyDescriptor = (
target: object,
key: string,
desc: PropertyDescriptor
) => PropertyDescriptor;

export const tracked = (trackedFn as any) as trackedWithPropertyDescriptor;
7 changes: 0 additions & 7 deletions addon/-private/live-query.js

This file was deleted.

64 changes: 64 additions & 0 deletions addon/-private/live-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import Helper from '@ember/component/helper';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import {
QueryOrExpressions,
buildQuery,
Query,
RequestOptions
} from '@orbit/data';
import { SyncLiveQueryUpdate, QueryResult } from '@orbit/record-cache';
import {
registerDestructor,
unregisterDestructor
} from 'ember-destroyable-polyfill';

import Store from '../-private/store';

export class LiveQuery extends Helper {
@service store!: Store;
@tracked update?: SyncLiveQueryUpdate;

#unsubscribe?: () => void;
#queryKey?: string;

get data(): QueryResult {
if (this.update) {
return this.store.cache.lookup(this.update.query());
}
return null;
}

compute(
[queryOrExpressions]: [QueryOrExpressions],
{ options, id }: { options: RequestOptions; id?: string }
) {
const query = buildQuery(queryOrExpressions, options, id);
const queryKey = JSON.stringify(query);

if (this.#queryKey !== queryKey) {
this.#queryKey = queryKey;
this.subscribeLiveQuery(query);
}

return this.data;
}

private subscribeLiveQuery(query: Query): void {
if (this.#unsubscribe) {
unregisterDestructor(this, this.#unsubscribe);
}

const liveQuery = this.store.source.cache.liveQuery(query);
const unsubscribe = liveQuery.subscribe((update) => {
this.update = update;
});

this.#unsubscribe = () => {
unsubscribe();
this.#unsubscribe = undefined;
this.update = undefined;
};
registerDestructor(this, this.#unsubscribe);
}
}
14 changes: 0 additions & 14 deletions addon/-private/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,6 @@ export default class Store {
this.source.rebase();
}

liveQuery(
queryOrExpressions: QueryOrExpressions,
options?: RequestOptions,
id?: string
): Promise<any> {
const query = buildQuery(
queryOrExpressions,
options,
id,
this.source.queryBuilder
);
return this.source.query(query).then(() => this.cache.liveQuery(query));
}

async query(
queryOrExpressions: QueryOrExpressions,
options?: RequestOptions,
Expand Down
1 change: 1 addition & 0 deletions addon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export { default as key } from './-private/fields/key';
export { default as Cache } from './-private/cache';
export { default as Model } from './-private/model';
export { default as Store } from './-private/store';
export * from './helpers/live-query';
// Provide `belongsTo` as an alias to `hasOne`
export { default as belongsTo } from './-private/fields/has-one';
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"ember-auto-import": "^1.5.3",
"ember-cli-babel": "^7.20.0",
"ember-cli-typescript": "^3.1.3",
"ember-destroyable-polyfill": "^0.4.0",
"ember-inflector": "^3.0.1",
"reflect-metadata": "^0.1.13"
},
Expand Down
8 changes: 0 additions & 8 deletions types/glimmer.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
declare module '@glimmer/env' {
export const DEBUG: boolean;
}

declare module '@glimmer/tracking' {
export function tracked(
target: object,
key: string,
desc: PropertyDescriptor
): PropertyDescriptor;
}
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4893,6 +4893,15 @@ ember-cli@~3.18.0:
watch-detector "^1.0.0"
yam "^1.0.0"

ember-destroyable-polyfill@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/ember-destroyable-polyfill/-/ember-destroyable-polyfill-0.4.0.tgz#3411c4cb11b711b8cdf14ae1d78ae3f905d9d9d9"
integrity sha512-SKRpqxK5JsrCHQWhSn5Hl7Yz4W/too/NmBN3Z3E5JNfEaApd0AcMupjUYyYNQ2Uo3pmySyOZz1hSdmbR84UArw==
dependencies:
ember-cli-babel "^7.18.0"
ember-cli-typescript "^3.1.3"
ember-cli-version-checker "^5.0.2"

ember-disable-prototype-extensions@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/ember-disable-prototype-extensions/-/ember-disable-prototype-extensions-1.1.3.tgz#1969135217654b5e278f9fe2d9d4e49b5720329e"
Expand Down

0 comments on commit 0d80a0e

Please sign in to comment.