diff --git a/.changeset/plenty-carrots-confess.md b/.changeset/plenty-carrots-confess.md new file mode 100644 index 0000000000..1387000cf6 --- /dev/null +++ b/.changeset/plenty-carrots-confess.md @@ -0,0 +1,5 @@ +--- +'@urql/core': patch +--- + +Remove `for-of` syntax from `@urql/core` helpers for JSC memory reduction. diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 0cf9b74fc3..6f196003b9 100755 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -649,7 +649,8 @@ export const Client: new (opts: ClientOptions) => Client = function Client( } else { // If the current result has queued up an operation of the same // key, then `stale` refers to it - for (const operation of queue) { + for (let i = 0; i < queue.length; i++) { + const operation = queue[i]; if (operation.key === result.operation.key) { dispatched.delete(operation.key); break; diff --git a/packages/core/src/gql.ts b/packages/core/src/gql.ts index 1254e74a6c..d5505a31fd 100644 --- a/packages/core/src/gql.ts +++ b/packages/core/src/gql.ts @@ -78,8 +78,9 @@ function gql(parts: string | TemplateStringsArray /* arguments */) { } source.unshift(keyDocument(body)); - for (const document of source) { - for (const definition of document.definitions) { + for (let i = 0; i < source.length; i++) { + for (let j = 0; j < source[i].definitions.length; j++) { + const definition = source[i].definitions[j]; if (definition.kind === Kind.FRAGMENT_DEFINITION) { const name = definition.name.value; const value = stringifyDocument(definition); diff --git a/packages/core/src/utils/collectTypenames.ts b/packages/core/src/utils/collectTypenames.ts index 0b4e3cbb07..a9d6091551 100755 --- a/packages/core/src/utils/collectTypenames.ts +++ b/packages/core/src/utils/collectTypenames.ts @@ -5,7 +5,9 @@ interface EntityLike { const collectTypes = (obj: EntityLike | EntityLike[], types: Set) => { if (Array.isArray(obj)) { - for (const item of obj) collectTypes(item, types); + for (let i = 0, l = obj.length; i < l; i++) { + collectTypes(obj[i], types); + } } else if (typeof obj === 'object' && obj !== null) { for (const key in obj) { if (key === '__typename' && typeof obj[key] === 'string') { diff --git a/packages/core/src/utils/error.ts b/packages/core/src/utils/error.ts index eeae84df6e..102f2f45f8 100644 --- a/packages/core/src/utils/error.ts +++ b/packages/core/src/utils/error.ts @@ -8,9 +8,9 @@ const generateErrorMessage = ( let error = ''; if (networkErr) return `[Network] ${networkErr.message}`; if (graphQlErrs) { - for (const err of graphQlErrs) { + for (let i = 0, l = graphQlErrs.length; i < l; i++) { if (error) error += '\n'; - error += `[GraphQL] ${err.message}`; + error += `[GraphQL] ${graphQlErrs[i].message}`; } } return error; diff --git a/packages/core/src/utils/formatDocument.ts b/packages/core/src/utils/formatDocument.ts index 3042f28187..da04dd4071 100644 --- a/packages/core/src/utils/formatDocument.ts +++ b/packages/core/src/utils/formatDocument.ts @@ -16,8 +16,8 @@ const formatNode = < ): FormattedNode => { if ('definitions' in node) { const definitions: FormattedNode[] = []; - for (const definition of node.definitions) { - const newDefinition = formatNode(definition); + for (let i = 0, l = node.definitions.length; i < l; i++) { + const newDefinition = formatNode(node.definitions[i]); definitions.push(newDefinition); } @@ -27,7 +27,8 @@ const formatNode = < if ('directives' in node && node.directives && node.directives.length) { const directives: DirectiveNode[] = []; const _directives = {}; - for (const directive of node.directives) { + for (let i = 0, l = node.directives.length; i < l; i++) { + const directive = node.directives[i]; let name = directive.name.value; if (name[0] !== '_') { directives.push(directive); @@ -43,7 +44,8 @@ const formatNode = < const selections: FormattedNode[] = []; let hasTypename = node.kind === Kind.OPERATION_DEFINITION; if (node.selectionSet) { - for (const selection of node.selectionSet.selections || []) { + for (let i = 0, l = node.selectionSet.selections.length; i < l; i++) { + const selection = node.selectionSet.selections[i]; hasTypename = hasTypename || (selection.kind === Kind.FIELD && diff --git a/packages/core/src/utils/request.ts b/packages/core/src/utils/request.ts index f0675c82b1..41af16f3dc 100644 --- a/packages/core/src/utils/request.ts +++ b/packages/core/src/utils/request.ts @@ -180,7 +180,8 @@ export const createRequest = < * @returns the operation's name contained within the document, or `undefined` */ export const getOperationName = (query: DocumentNode): string | undefined => { - for (const node of query.definitions) { + for (let i = 0, l = query.definitions.length; i < l; i++) { + const node = query.definitions[i]; if (node.kind === Kind.OPERATION_DEFINITION) { return node.name ? node.name.value : undefined; } @@ -192,7 +193,8 @@ export const getOperationName = (query: DocumentNode): string | undefined => { * @returns the operation's type contained within the document, or `undefined` */ export const getOperationType = (query: DocumentNode): string | undefined => { - for (const node of query.definitions) { + for (let i = 0, l = query.definitions.length; i < l; i++) { + const node = query.definitions[i]; if (node.kind === Kind.OPERATION_DEFINITION) { return node.operation; } diff --git a/packages/core/src/utils/result.ts b/packages/core/src/utils/result.ts index 119081ccdd..81c04d4b8c 100644 --- a/packages/core/src/utils/result.ts +++ b/packages/core/src/utils/result.ts @@ -53,13 +53,18 @@ export const makeResult = ( const deepMerge = (target: any, source: any): any => { if (typeof target === 'object' && target != null) { + if (Array.isArray(target)) { + target = [...target]; + for (let i = 0, l = source.length; i < l; i++) + target[i] = deepMerge(target[i], source[i]); + } if ( !target.constructor || target.constructor === Object || Array.isArray(target) ) { - target = Array.isArray(target) ? [...target] : { ...target }; - for (const key of Object.keys(source)) + target = { ...target }; + for (const key in source) target[key] = deepMerge(target[key], source[key]); return target; } @@ -108,7 +113,8 @@ export const mergeResultPatch = ( const withData = { data: prevResult.data }; if (incremental) { - for (const patch of incremental) { + for (let i = 0, l = incremental.length; i < l; i++) { + const patch = incremental[i]; if (Array.isArray(patch.errors)) { errors.push(...(patch.errors as any)); } diff --git a/packages/core/src/utils/variables.ts b/packages/core/src/utils/variables.ts index fb3cf50f17..360067365c 100644 --- a/packages/core/src/utils/variables.ts +++ b/packages/core/src/utils/variables.ts @@ -12,9 +12,9 @@ const stringify = (x: any, includeFiles: boolean): string => { return stringify(x.toJSON(), includeFiles); } else if (Array.isArray(x)) { let out = '['; - for (const value of x) { + for (let i = 0, l = x.length; i < l; i++) { if (out.length > 1) out += ','; - out += stringify(value, includeFiles) || 'null'; + out += stringify(x[i], includeFiles) || 'null'; } out += ']'; return out; @@ -39,11 +39,11 @@ const stringify = (x: any, includeFiles: boolean): string => { seen.add(x); let out = '{'; - for (const key of keys) { - const value = stringify(x[key], includeFiles); + for (let i = 0, l = keys.length; i < l; i++) { + const value = stringify(x[keys[i]], includeFiles); if (value) { if (out.length > 1) out += ','; - out += stringify(key, includeFiles) + ':' + value; + out += stringify(keys[i], includeFiles) + ':' + value; } } @@ -62,7 +62,7 @@ const extract = (map: FileMap, path: string, x: any): void => { map.set(path, x as File | Blob); } else { seen.add(x); - for (const key of Object.keys(x)) extract(map, `${path}.${key}`, x[key]); + for (const key in x) extract(map, `${path}.${key}`, x[key]); } };