Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,23 @@ module.exports = {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true
}
legacyDecorators: true,
},
},
plugins: [
'ember'
],
plugins: ['ember'],
extends: [
'eslint:recommended',
'plugin:ember/recommended',
'plugin:prettier/recommended',
],
env: {
browser: true
browser: true,
},
rules: {
'ember/no-jquery': 'off',
'ember/no-mixins': 'off',
'ember/no-new-mixins': 'off',
'no-useless-escape': 'off'
'no-useless-escape': 'off',
},
overrides: [
// node files
Expand All @@ -46,11 +44,11 @@ module.exports = {
'./tests/dummy/config/**/*.js',
],
parserOptions: {
sourceType: 'script'
sourceType: 'script',
},
env: {
browser: false,
node: true
node: true,
},
plugins: ['node'],
extends: ['plugin:node/recommended'],
Expand Down
6 changes: 2 additions & 4 deletions addon/-private/cache.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { queryCacheKey, cacheKey } from './utils/get-key';
import { queryCacheKey, cacheKey } from './utils/get-key';

/*
A cache for queries.
*/
export default class Cache {

constructor() {
this.store = {};
}
Expand All @@ -21,7 +20,6 @@ export default class Cache {
}

all() {
return Object.keys(this.store).map(key => this.store[key]);
return Object.keys(this.store).map((key) => this.store[key]);
}

}
30 changes: 16 additions & 14 deletions addon/-private/coordinator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@ import { get } from '@ember/object';

// cleans options so that the resulting object only contains
// data we want to send to the server as query params.
let _cleanParams = function(options) {
let _cleanParams = function (options) {
let clean = { ...{}, ...options };
delete clean.reload;
delete clean.backgroundReload;
return clean;
}
};

/*
I know how to retrieve queries from the cache, and also assemble queries that
are not in the cache but can be derived from them.
*/
export default class Coordinator {

constructor(store) {
this.store = store;
this.recordCache = new Cache();
Expand Down Expand Up @@ -52,9 +51,9 @@ export default class Coordinator {
}

queryFor(...args) {
return args.length === 3 ?
this.recordQueryFor(...args) :
this.recordArrayQueryFor(...args);
return args.length === 3
? this.recordQueryFor(...args)
: this.recordArrayQueryFor(...args);
}

dump() {
Expand All @@ -65,7 +64,9 @@ export default class Coordinator {
}

recordHasIncludes(type, id, includesString) {
let query = this._assembleRecordQuery(type, id, { include: includesString });
let query = this._assembleRecordQuery(type, id, {
include: includesString,
});
let nonLoadedIncludes = this._nonLoadedIncludesForQuery(query);

return nonLoadedIncludes.length === 0;
Expand Down Expand Up @@ -99,16 +100,17 @@ export default class Coordinator {
}

_nonLoadedIncludesForQuery(query) {
let loadedIncludes = get(this, `loadedIncludes.${query.type}.${query.id}`) || [];
let loadedIncludes =
get(this, `loadedIncludes.${query.type}.${query.id}`) || [];
let includesString = query.params.include || '';

return includesString
.split(',')
.filter(include => !!include)
.filter(include => {
return !loadedIncludes.find(loadedInclude => {
.filter((include) => !!include)
.filter((include) => {
return !loadedIncludes.find((loadedInclude) => {
return loadedInclude.indexOf(include) === 0;
})
});
});
}

Expand All @@ -123,13 +125,13 @@ export default class Coordinator {

_updateLoadedIncludesWithQuery(query) {
this.loadedIncludes[query.type] = this.loadedIncludes[query.type] || {};
this.loadedIncludes[query.type][query.id] = this.loadedIncludes[query.type][query.id] || [];
this.loadedIncludes[query.type][query.id] =
this.loadedIncludes[query.type][query.id] || [];

let currentIncludes = this.loadedIncludes[query.type][query.id];
let nonLoadedIncludes = this._nonLoadedIncludesForQuery(query);
let newLoadedIncludes = [...currentIncludes, ...nonLoadedIncludes];

this.loadedIncludes[query.type][query.id] = newLoadedIncludes;
}

}
16 changes: 6 additions & 10 deletions addon/-private/record-array-query.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export default class RecordArrayQuery {

constructor(store, type, params = {}) {
this.store = store;
this.type = type;
Expand All @@ -13,14 +12,12 @@ export default class RecordArrayQuery {

if (this.value) {
promise = this.value.update();

} else {
promise = this.store.query(this.type, this.params)
.then(records => {
this.value = records;
promise = this.store.query(this.type, this.params).then((records) => {
this.value = records;

return records;
});
return records;
});
}

return promise;
Expand All @@ -30,13 +27,12 @@ export default class RecordArrayQuery {
let includes = this.params && this.params.include;
let models = this.value;

if (includes && models) {
if (includes && models) {
models
.filter(model => model.trackLoadedIncludes)
.filter((model) => model.trackLoadedIncludes)
.forEach((model) => {
model.trackLoadedIncludes(includes);
});
}
}

}
18 changes: 8 additions & 10 deletions addon/-private/record-query.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export default class RecordQuery {

constructor(store, type, id, params = {}) {
this.store = store;
this.type = type;
Expand All @@ -8,22 +7,21 @@ export default class RecordQuery {

// if we have no params, we can use the model from
// the store if it exists, nice lil shortcut here.
this.value = Object.keys(this.params).length === 0 ?
this.store.peekRecord(type, id) :
null;
this.value =
Object.keys(this.params).length === 0
? this.store.peekRecord(type, id)
: null;
}

run() {
// if we're running a query in storefront we always want
// a blocking promise, so we force reload true.
let options = { ...{ reload: true }, ...this.params };

return this.store.findRecord(this.type, this.id, options)
.then(record => {
this.value = record;
return this.store.findRecord(this.type, this.id, options).then((record) => {
this.value = record;

return record;
});
return record;
});
}

}
31 changes: 13 additions & 18 deletions addon/-private/utils/get-key.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
let _serializeParams = function(params={}, prefix) {
let _serializeParams = function (params = {}, prefix) {
const query = Object.keys(params)
.sort()
.map((key) => {
const value = params[key];
const value = params[key];

if (Array.isArray(params)) {
key = `${prefix}[]`;
} else if (params === Object(params)) {
key = (prefix ? `${prefix}[${key}]` : key);
key = prefix ? `${prefix}[${key}]` : key;
}

if (typeof value === 'object' && value !== null) {
Expand All @@ -20,28 +20,23 @@ let _serializeParams = function(params={}, prefix) {
return [].concat.apply([], query).join('&');
};

let serializeObject = function(params) {
let serializeObject = function (params) {
return _serializeParams(params);
};

let queryCacheKey = function(query) {
let queryCacheKey = function (query) {
return cacheKey([query.type, query.id, query.params]);
};

let cacheKey = function(args) {
let cacheKey = function (args) {
return args
.map(part => typeof part === "object" ? serializeObject(part) : part)
.filter(part => !!part)
.map((part) => (typeof part === 'object' ? serializeObject(part) : part))
.filter((part) => !!part)
.join('::');
}
};

let shoeboxize = function(key) {
let shoeboxize = function (key) {
return key.replace(/&/g, '--'); // IDGAF
}

export {
serializeObject,
queryCacheKey,
cacheKey,
shoeboxize
}
};

export { serializeObject, queryCacheKey, cacheKey, shoeboxize };
2 changes: 1 addition & 1 deletion addon/adapters/application.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import JSONAPIAdapter from '@ember-data/adapter/json-api';

export default class ApplicationAdapter extends JSONAPIAdapter {}
export default class ApplicationAdapter extends JSONAPIAdapter {}
8 changes: 4 additions & 4 deletions addon/components/assert-must-preload/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import Component from '@glimmer/component';
import { assert } from '@ember/debug';

export default class AssertMustPreloadComponent extends Component {

/**
/**
_This component relies on JSON:API, and assumes that your server supports JSON:API includes._

_<AssertMustPreload /> only works on models that have included the LoadableModel mixin._
Expand Down Expand Up @@ -32,7 +31,9 @@ export default class AssertMustPreloadComponent extends Component {

const { model, includes } = this.args;
let parentComponent = this.parentView;
let parentName = parentComponent ? parentComponent._debugContainerKey : 'template';
let parentName = parentComponent
? parentComponent._debugContainerKey
: 'template';
let includesString = includes.join(',');

assert(
Expand All @@ -45,5 +46,4 @@ export default class AssertMustPreloadComponent extends Component {
model.hasLoaded(includesString)
);
}

}
2 changes: 1 addition & 1 deletion addon/instance-initializers/inject-storefront.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export function initialize(appInstance) {
export default {
name: 'inject-storefront',
after: 'mixin-storefront',
initialize
initialize,
};
2 changes: 1 addition & 1 deletion addon/instance-initializers/mixin-storefront.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ export function initialize(appInstance) {
export default {
name: 'mixin-storefront',
after: 'ember-data',
initialize
initialize,
};
Loading