Deprecation of attachOperation 
This ADR is effective starting from v0.12.
TL;DR
attachOperation is a bad abstraction because it is not clear what it does, and it is not clear what it is supposed to do. Furthermore, it can be replaced by a more explicit and more flexible plain JS functions.
 function createOriginalQuery() {
  return createQuery(/*...*/);
}
const originalQuery = createQuery(/*...*/); 
const originalQuery = createOriginalQuery(); 
const copiedQuery = attachOperation(originalQuery); 
const copiedQuery = createOriginalQuery(); Issues with attachOperation 
Let us take a closer look at problems with attachOperation.
Understanding 
attachOperation is a function that takes a Query (or Mutation) and returns a copy of it. However, it is not clear what it does with some additional behavior added to Query. For example, let us say that we have the following code:
import { createQuery, cache, attachOperation } from '@farfetched/core';
const originalQuery = createQuery(/*...*/);
cache(originalQuery);
const copiedQuery = attachOperation(originalQuery);Should copiedQuery be cached? Should it use the same cache strategy as originalQuery, or should it share cache with originalQuery? The answer is not clear, and it is not clear because attachOperation is not a good abstraction.
However, if we replace attachOperation with a plain JS function, it becomes clear what it does:
import { createQuery, cache } from '@farfetched/core';
function createOriginalQuery() {
  const q = createQuery(/*...*/);
  cache(q);
  return q;
}
const originalQuery = createOriginalQuery();
const copiedQuery = createOriginalQuery();Now it is crystal clear that copiedQuery should be cached with the same cache strategy as originalQuery, but they should not share cache.
The same applies to other behaviors that can be added to Query or Mutation. For example, the following code example:
import { createQuery, retry, attachOperation } from '@farfetched/core';
const originalQuery = createQuery(/*...*/);
retry(originalQuery, {
  times: 5,
});
const copiedQuery = attachOperation(originalQuery);Same questions. Should copiedQuery retry? Should it use the same retry strategy as originalQuery, or should it share the whole retry state (how many retries are already over, etc.) with originalQuery? Replacing attachOperation with a plain JS function makes it clear and explicit:
import { createQuery, retry } from '@farfetched/core';
function createOriginalQuery() {
  const q = createQuery(/*...*/);
  retry(q, {
    times: 5,
  });
  return q;
}
const originalQuery = createOriginalQuery();
const copiedQuery = createOriginalQuery();Since we are trying to make Farfetched as explicit as possible, we should not use attachOperation anymore.
Extensibility 
attachOperation is mimic of attach from Effector which has an ability of altering parameters of the original Effect. This ability was copied "as is" to attachOperation, and it works great. However, Query and Mutation are way more complex than Effect, so it is required to extend attachOperation for almost every new feature. A couple of examples:
- Feature request: 
mapDataforattachOperation - Feature request: altering 
concurrencyinattachOperation 
The solution is to replace attachOperation with a plain JS function does not require any changes because it is just a function. Users can alter it as they want without any limitations.
Future of attachOperation 
How to migrate 
Let us describe migration paths for all possible use cases of attachOperation.
TIP
You can check an example of migration of SolidJS Real-world Example.
attachOperation(originalQuery) 
This overload is used to create a copy of Query or Mutation without any modifications. It can be replaced with a plain JS function:
 function createOriginalQuery() {
  return createQuery(/*...*/);
}
const originalQuery = createQuery(/*...*/); 
const originalQuery = createOriginalQuery(); 
const copiedQuery = attachOperation(originalQuery); 
const copiedQuery = createOriginalQuery(); @withease/factories
If your application has SSR you can use @withease/factories to create a factory function with ease:
import { createFactory } from '@withease/factories'; 
const createOriginalQuery = createFactory(() => { 
function createOriginalQuery() { 
  return createQuery(/*...*/);
});Read more about it in the documentation of @withease/factories.
attachOperation(originalQuery, { mapParams }) 
This overload allows altering parameters of the original Query or Mutation. It can be replaced with a plain JS function as well:
 function createOriginalQuery({ mapParams } = {}) {
  return createQuery({
    effect(rawParams) {
      const params = mapParams ? mapParams(rawParams) : rawParams;
      return fetch(/*...*/);
    },
  });
}
 const originalQuery = createQuery({
  effect(params) {
    return fetch(/*...*/);
  },
});
const originalQuery = createOriginalQuery(); 
 const copiedQuery = attachOperation(originalQuery, {
  mapParams: p + 1,
});
const copiedQuery = createOriginalQuery({ mapParams: (p) => p + 1 }); Deletion schedule 
attachOperation(originalQuery)will be marked as deprecated in v0.12 with a warning in JSDoc and on TS-level.attachOperation(originalQuery)will start writing deprecation message withconsole.warningin v0.13.attachOperation(originalQuery)will be deleted in v0.14.