Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove lodash as a production dependency #1122

Merged
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
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Authors
Abhi Aiyer <abhiaiyer91@gmail.com>
Brady Whitten <bwhitten518@gmail.com>
Bruce Williams <brwcodes@gmail.com>
Caleb Meredith <calebmeredith8@gmail.com>
Carl Wolsey <carl@wolsey.org>
Clément Prévost <prevostclement@gmail.com>
David Alan Hjelle <dahjelle+github.com@thehjellejar.com>
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Expect active development and potentially significant breaking changes in the `0

- Remove fragment option from query, watchQuery etc. [PR #1096](https://github.com/apollostack/apollo-client/pull/1096)
- Broadcast new store state only when Apollo state was affected by an action [PR #1118](https://github.com/apollostack/apollo-client/pull/1118)
- Remove lodash as a production dependency [PR #1122](https://github.com/apollostack/apollo-client/pull/1122)

### 0.5.26
- Add variables to MutationResultAction [PR #1106](https://github.com/apollostack/apollo-client/pull/1106)
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"dependencies": {
"graphql-anywhere": "^1.0.0",
"graphql-tag": "^1.1.1",
"lodash": "^4.17.2",
"redux": "^3.4.0",
"symbol-observable": "^1.0.2",
"whatwg-fetch": "^2.0.0"
Expand Down
7 changes: 2 additions & 5 deletions src/ApolloClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import {

} from 'graphql';

import isUndefined from 'lodash/isUndefined';
import isString from 'lodash/isString';

import {
createApolloStore,
ApolloStore,
Expand Down Expand Up @@ -183,7 +180,7 @@ export default class ApolloClient {

if (!reduxRootSelector && reduxRootKey) {
this.reduxRootSelector = (state: any) => state[reduxRootKey];
} else if (isString(reduxRootSelector)) {
} else if (typeof reduxRootSelector === 'string') {
// for backwards compatibility, we set reduxRootKey if reduxRootSelector is a string
this.reduxRootKey = reduxRootSelector as string;
this.reduxRootSelector = (state: any) => state[reduxRootSelector as string];
Expand Down Expand Up @@ -438,7 +435,7 @@ export default class ApolloClient {
}

// ensure existing store has apolloReducer
if (isUndefined(reduxRootSelector(store.getState()))) {
if (typeof reduxRootSelector(store.getState()) === 'undefined') {
throw new Error(
'Existing store does not use apolloReducer. Please make sure the store ' +
'is properly configured and "reduxRootSelector" is correctly specified.',
Expand Down
4 changes: 2 additions & 2 deletions src/core/ObservableQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import {

import { tryFunctionOrLogError } from '../util/errorHandling';

import { NetworkStatus } from '../queries/store';
import { isEqual } from '../util/isEqual';

import isEqual from 'lodash/isEqual';
import { NetworkStatus } from '../queries/store';

export type ApolloCurrentResult = {
data: any;
Expand Down
6 changes: 3 additions & 3 deletions src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
Deduplicator,
} from '../transport/Deduplicator';

import forOwn from 'lodash/forOwn';
import isEqual from 'lodash/isEqual';
import { isEqual } from '../util/isEqual';

import {
ResultTransformer,
Expand Down Expand Up @@ -1016,7 +1015,8 @@ export class QueryManager {

private broadcastQueries() {
const queries = this.getApolloState().queries;
forOwn(this.queryListeners, (listeners: QueryListener[], queryId: string) => {
Object.keys(this.queryListeners).forEach((queryId: string) => {
const listeners = this.queryListeners[queryId];
// XXX due to an unknown race condition listeners can sometimes be undefined here.
// this prevents a crash but doesn't solve the root cause
// see: https://github.com/apollostack/apollo-client/issues/833
Expand Down
15 changes: 8 additions & 7 deletions src/data/debug.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
// For development only!
import isObject from 'lodash/isObject';
import omit from 'lodash/omit';
import mapValues from 'lodash/mapValues';

export function stripLoc(obj: Object) {
if (Array.isArray(obj)) {
return obj.map(stripLoc);
}

if (! isObject(obj)) {
if (obj === null || typeof obj !== 'object') {
return obj;
}

const omitted: Object = omit(obj, ['loc']);
const nextObj = {};

return mapValues(omitted, (value) => {
return stripLoc(value);
Object.keys(obj).forEach(key => {
if (key !== 'loc') {
nextObj[key] = stripLoc(obj[key]);
}
});

return nextObj;
}

export function printAST(fragAst: Object) {
Expand Down
26 changes: 17 additions & 9 deletions src/data/mutationResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
GraphQLResult,
} from 'graphql';

import mapValues from 'lodash/mapValues';
import cloneDeep from 'lodash/cloneDeep';
import { cloneDeep } from '../util/cloneDeep';

import { replaceQueryResults } from './replaceQueryResults';

Expand Down Expand Up @@ -183,8 +182,11 @@ function mutationResultDeleteReducer(state: NormalizedCache, {
delete state[dataId];

// Now we need to go through the whole store and remove all references
const newState = mapValues(state, (storeObj: StoreObject) => {
return removeRefsFromStoreObj(storeObj, dataId);
const newState: NormalizedCache = {};

Object.keys(state).forEach(key => {
const storeObj = state[key];
newState[key] = removeRefsFromStoreObj(storeObj, dataId);
});

return newState;
Expand All @@ -193,23 +195,29 @@ function mutationResultDeleteReducer(state: NormalizedCache, {
function removeRefsFromStoreObj(storeObj: any, dataId: any) {
let affected = false;

const cleanedObj = mapValues(storeObj, (value: any) => {
const cleanedObj: any = {};

Object.keys(storeObj).forEach(key => {
const value = storeObj[key];

if (value && value.id === dataId) {
affected = true;
return null;
cleanedObj[key] = null;
return;
}

if (Array.isArray(value)) {
const filteredArray = cleanArray(value, dataId);

if (filteredArray !== value) {
affected = true;
return filteredArray;
cleanedObj[key] = filteredArray;
return;
}
}

// If not modified, return the original value
return value;
// If not modified, set the original value
cleanedObj[key] = value;
});

if (affected) {
Expand Down
4 changes: 1 addition & 3 deletions src/data/scopeQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import {
resultKeyNameFromField,
} from './storeUtils';

import isNumber from 'lodash/isNumber';

// The type of a path
export type StorePath = (string|number)[];

Expand Down Expand Up @@ -51,7 +49,7 @@ export function scopeSelectionSetToResultPath({

path
// Arrays are not represented in GraphQL AST
.filter((pathSegment) => !isNumber(pathSegment))
.filter((pathSegment) => typeof pathSegment !== 'number')
.forEach((pathSegment) => {
currSelSet = followOnePathSegment(currSelSet, pathSegment as string, fragmentMap);
});
Expand Down
14 changes: 10 additions & 4 deletions src/data/storeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import {
Name,
} from 'graphql';

import isObject from 'lodash/isObject';

function isStringValue(value: Value): value is StringValue {
return value.kind === 'StringValue';
}
Expand Down Expand Up @@ -146,7 +144,11 @@ export interface JsonValue {
export type StoreValue = number | string | string[] | IdValue | JsonValue | void;

export function isIdValue(idObject: StoreValue): idObject is IdValue {
return (isObject(idObject) && (idObject as (IdValue | JsonValue)).type === 'id');
return (
idObject != null &&
typeof idObject === 'object' &&
(idObject as (IdValue | JsonValue)).type === 'id'
);
}

export function toIdValue(id: string, generated = false): IdValue {
Expand All @@ -158,5 +160,9 @@ export function toIdValue(id: string, generated = false): IdValue {
}

export function isJsonValue(jsonObject: StoreValue): jsonObject is JsonValue {
return (isObject(jsonObject) && (jsonObject as (IdValue | JsonValue)).type === 'json');
return (
jsonObject != null &&
typeof jsonObject === 'object' &&
(jsonObject as (IdValue | JsonValue)).type === 'json'
);
}
26 changes: 11 additions & 15 deletions src/data/writeToStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import isObject from 'lodash/isObject';

import {
getOperationDefinition,
Expand Down Expand Up @@ -149,7 +146,7 @@ export function writeSelectionSetToStore({
const resultFieldKey: string = resultKeyNameFromField(selection);
const value: any = result[resultFieldKey];

if (!isUndefined(value)) {
if (value !== undefined) {
writeFieldToStore({
dataId,
value,
Expand Down Expand Up @@ -241,16 +238,15 @@ function writeFieldToStore({
// If we merge, this will be the generatedKey
let generatedKey: string;

// If it's a scalar that's not a JSON blob, just store it in the store
if ((!field.selectionSet || isNull(value)) && !isObject(value)) {
storeValue = value;
} else if ((!field.selectionSet || isNull(value)) && isObject(value)) {
// If it is a scalar that's a JSON blob, we have to "escape" it so it can't
// pretend to be an id
storeValue = {
type: 'json',
json: value,
};
// If this is a scalar value...
if (!field.selectionSet || value === null) {
storeValue =
value != null && typeof value === 'object'
// If the scalar value is a JSON blob, we have to "escape" it so it can’t pretend to be
// an id.
? { type: 'json', json: value }
// Otherwise, just store the scalar directly in the store.
: value;
} else if (Array.isArray(value)) {
const generatedId = `${dataId}.${storeFieldName}`;

Expand Down Expand Up @@ -340,7 +336,7 @@ function processArrayValue(
context: WriteContext,
): any[] {
return value.map((item: any, index: any) => {
if (isNull(item)) {
if (item === null) {
return null;
}

Expand Down
13 changes: 8 additions & 5 deletions src/optimistic-data/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import {
Store,
} from '../store';

import assign from 'lodash/assign';
import pick from 'lodash/pick';
import { assign } from '../util/assign';

// a stack of patches of new or changed documents
export type OptimisticStore = {
Expand Down Expand Up @@ -69,9 +68,13 @@ export function optimistic(

// TODO: apply extra reducers and resultBehaviors to optimistic store?

const changedKeys = Object.keys(fakeDataResultState).filter(
key => optimisticData[key] !== fakeDataResultState[key]);
const patch = pick(fakeDataResultState, changedKeys);
const patch: any = {};

Object.keys(fakeDataResultState).forEach(key => {
if (optimisticData[key] !== fakeDataResultState[key]) {
patch[key] = fakeDataResultState[key];
}
});

const optimisticState = {
data: patch,
Expand Down
47 changes: 18 additions & 29 deletions src/queries/getFromAST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import {
FragmentDefinition,
} from 'graphql';

import countBy from 'lodash/countBy';
import identity from 'lodash/identity';
import uniq from 'lodash/uniq';

export function getMutationDefinition(doc: Document): OperationDefinition {
checkDocument(doc);

Expand All @@ -33,19 +29,26 @@ export function checkDocument(doc: Document) {
string in a "gql" tag? http://docs.apollostack.com/apollo-client/core.html#gql`);
}

const definitionTypes = doc.definitions.map((definition) => {
if (definition.kind !== 'OperationDefinition' && definition.kind !== 'FragmentDefinition') {
throw new Error(`Schema type definitions not allowed in queries. Found: "${definition.kind}"`);
}
let foundOperation = false;

return definition.kind;
doc.definitions.forEach((definition) => {
switch (definition.kind) {
// If this is a fragment that’s fine.
case 'FragmentDefinition':
break;
// We can only find one operation, so the first time nothing happens. The second time we
// encounter an operation definition we throw an error.
case 'OperationDefinition':
if (foundOperation) {
throw new Error('Queries must have exactly one operation definition.');
}
foundOperation = true;
break;
// If this is any other operation kind, throw an error.
default:
throw new Error(`Schema type definitions not allowed in queries. Found: "${definition.kind}"`);
}
});
const typeCounts = countBy(definitionTypes, identity);

// can't have more than one operation definition per query
if (typeCounts['OperationDefinition'] > 1) {
throw new Error('Queries must have exactly one operation definition.');
}
}

export function getOperationName(doc: Document): string {
Expand Down Expand Up @@ -144,17 +147,3 @@ export function createFragmentMap(fragments: FragmentDefinition[] = []): Fragmen

return symTable;
}

// Utility function that takes a list of fragment definitions and adds them to a particular
// document.
export function addFragmentsToDocument(queryDoc: Document,
fragments: FragmentDefinition[]): Document {
if (!fragments) {
return queryDoc;
}
checkDocument(queryDoc);
return {
...queryDoc,
definitions: uniq(queryDoc.definitions.concat(fragments)),
} as Document;
}
2 changes: 1 addition & 1 deletion src/queries/queryTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
checkDocument,
} from './getFromAST';

import cloneDeep from 'lodash/cloneDeep';
import { cloneDeep } from '../util/cloneDeep';

const TYPENAME_FIELD: Field = {
kind: 'Field',
Expand Down
2 changes: 1 addition & 1 deletion src/queries/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
GraphQLError,
} from 'graphql';

import isEqual from 'lodash/isEqual';
import { isEqual } from '../util/isEqual';

export interface QueryStore {
[queryId: string]: QueryStoreValue;
Expand Down
2 changes: 1 addition & 1 deletion src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import {
CustomResolverMap,
} from './data/readFromStore';

import assign from 'lodash/assign';
import { assign } from './util/assign';

export interface Store {
data: NormalizedCache;
Expand Down
Loading