<commit_before>import { types, isRoot, getParent } from "mobx-state-tree";

export const setupContext = (Model, key) => {
  if (typeof Model.name !== "string") {
    throw new Error("Name required for context model type!");
  }

  const KEY = key || `context${Model.name}`;
  const REFKEY = `${KEY}Ref`;

  let defaultContext;

  const getContext = node => {
    const context = node[KEY];

    if (context) {
      return context;
    }

    // TODO: should I leave in this defaultContext behavior?
    if (isRoot(node)) {
      if (defaultContext) {
        return defaultContext;
      }

      defaultContext = Model.create();
      return defaultContext;
      // throw new Error(`Could not find required Context ${Model.name}.`);
    }

    const parent = getParent(node);
    if (parent) {
      return getContext(parent);
    }

    return null;
  };

  const Ref = types.optional(
    types.union(
      Model,
      types.reference(Model, {
        set(val) {
          return 0;
        },
        get(identifier, parent) {
          return getContext(parent);
        }
      })
    ),
    0
  );

  const Mixin = {
    [KEY]: types.maybe(Model),
    [REFKEY]: Ref
  };

  const RefModel = types.model(`${Model.name}Ref`, Mixin).actions(self => ({
    postProcessSnapshot(snapshot) {
      delete snapshot[REFKEY];

      if (!snapshot[KEY]) {
        delete snapshot[KEY];
      }

      return snapshot;
    }
  }));

  const refModel = (...args) => types.compose(RefModel, types.model(...args));

  return { KEY, REFKEY, refModel, Ref, Mixin };
};

export const makeContext = Model => {
  const Context = types.model(
    `Context${Model.name}`,
    {
      _id: types.optional(types.identifier(types.number), 0)
    },
    Model
  );

  const contextRefKey = `context${Model.name}`;

  const ContextRef = types
    .model(`Context${Model.name}Child`, {
      [contextRefKey]: types.optional(types.reference(Context), 0)
    })
    .actions(self => ({
      postProcessSnapshot({ context, ...rest }) {
        return rest;
      }
    }));

  const refModel = (...args) => types.compose(ContextRef, types.model(...args));

  return {
    Type: Context,
    key: contextRefKey,
    refModel
  };
};<commit_msg>fix: properly compose generated context type<commit_after>import { types, isRoot, getParent } from "mobx-state-tree";

export const setupContext = (Model, key) => {
  if (typeof Model.name !== "string") {
    throw new Error("Name required for context model type!");
  }

  const KEY = key || `context${Model.name}`;
  const REFKEY = `${KEY}Ref`;

  let defaultContext;

  const getContext = node => {
    const context = node[KEY];

    if (context) {
      return context;
    }

    // TODO: should I leave in this defaultContext behavior?
    if (isRoot(node)) {
      if (defaultContext) {
        return defaultContext;
      }

      defaultContext = Model.create();
      return defaultContext;
      // throw new Error(`Could not find required Context ${Model.name}.`);
    }

    const parent = getParent(node);
    if (parent) {
      return getContext(parent);
    }

    return null;
  };

  const Ref = types.optional(
    types.union(
      Model,
      types.reference(Model, {
        set(val) {
          return 0;
        },
        get(identifier, parent) {
          return getContext(parent);
        }
      })
    ),
    0
  );

  const Mixin = {
    [KEY]: types.maybe(Model),
    [REFKEY]: Ref
  };

  const RefModel = types.model(`${Model.name}Ref`, Mixin).actions(self => ({
    postProcessSnapshot(snapshot) {
      delete snapshot[REFKEY];

      if (!snapshot[KEY]) {
        delete snapshot[KEY];
      }

      return snapshot;
    }
  }));

  const refModel = (...args) => types.compose(RefModel, types.model(...args));

  return { KEY, REFKEY, refModel, Ref, Mixin };
};

export const makeContext = Model => {
  const contextRefKey = `context${Model.name}`;

  const Context = types.model(`Context${Model.name}`, {
    _id: types.optional(types.identifier(types.number), 0)
  });

  const Type = types.compose(Model, Context);

  const ContextRef = types
    .model(`Context${Model.name}Child`, {
      [contextRefKey]: types.optional(types.reference(Type), 0)
    })
    .actions(self => ({
      postProcessSnapshot({ context, ...rest }) {
        return rest;
      }
    }));

  const refModel = (...args) => types.compose(ContextRef, types.model(...args));

  return {
    Type,
    key: contextRefKey,
    refModel
  };
};
{'fraction_non_alphanumeric': 0.14909739246712725, 'fraction_numerical': 0.0017829284599955428, 'mean_word_length': 2.4871794871794872, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6109190', 'n_tokens_mistral': 1400, 'n_tokens_neox': 1369, 'n_words': 326}