<commit_before>import { location, PREVIEW_URL } from 'global';
import {
  transformStoriesRawToStoriesHash,
  StoriesRaw,
  StoryInput,
  StoriesHash,
  isRoot,
} from '../lib/stories';

import { Module } from '../index';

export interface SubState {
  refs: Record<string, InceptionRef & { data: StoriesHash }>;
}

export interface SubAPI {
  setRef: (id: string, stories: StoriesRaw) => void;
  getRefs: () => Record<RefId, RefUrl>;
}

export type Mapper = (ref: InceptionRef, story: StoryInput) => StoryInput;
export interface InceptionRef {
  id: string;
  url: string;
}

export type RefId = string;
export type RefUrl = string;

export const getSourceType = (source: string) => {
  const { origin, pathname } = location;

  if (source === origin || source === `${origin + pathname}iframe.html`) {
    return 'local';
  }
  return 'external';
};

export const defaultMapper: Mapper = (b, a) => {
  return { ...a, kind: `${b.id}/${a.kind.replace('|', '/')}` };
};

const namespace = (input: StoriesHash, ref: InceptionRef, options: {}): StoriesHash => {
  const output = {} as StoriesHash;

  Object.entries(input).forEach(([id, item]) => {
    const mappedId = `${ref.id}_${item.id}`;
    const target = output[mappedId];

    Object.assign(target, item, {
      id: mappedId,
      // this is used later to emit the correct commands over the channel
      knownAs: id,
      // this is used to know which iframe to emit the message to
      ref,
    });

    if (!isRoot(item)) {
      const mappedParentId = `${ref.id}_${item.parent}`;

      Object.assign(target, {
        parent: mappedParentId,
      });
    }

    if (item.children) {
      Object.assign(target, {
        children: item.children.map(c => `${ref.id}_${c}`),
      });
    }
  });

  return output;
};

const map = (input: StoriesRaw, ref: InceptionRef, options: { mapper?: Mapper }): StoriesRaw => {
  const output = {} as StoriesRaw;
  // map the incoming stories to a prefixed, non-conflicting version
  Object.entries(input).forEach(([unmappedStoryId, unmappedStoryInput]) => {
    const mapped = options.mapper ? options.mapper(ref, unmappedStoryInput) : unmappedStoryInput;

    if (mapped) {
      output[unmappedStoryId] = mapped;
    }
  });
  return output;
};

const initRefsApi = ({ store, provider }: Module) => {
  const getRefs: SubAPI['getRefs'] = () => {
    const { refs = {} } = provider.getConfig();

    return refs;
  };

  const setRef: SubAPI['setRef'] = (id, data) => {
    const url = getRefs()[id];
    const ref = { id, url };
    const after = namespace(
      transformStoriesRawToStoriesHash(map(data, ref, { mapper: defaultMapper }), {}),
      ref,
      {}
    );

    store.setState({
      refs: {
        ...(store.getState().refs || {}),
        [id]: { id, url, data: after },
      },
    });
  };

  const initialState: SubState['refs'] = Object.entries(getRefs()).reduce(
    (acc, [key, value]) => ({
      ...acc,
      [key]: {
        id: key,
        url: value,
        data: {},
      },
    }),
    {}
  );

  return {
    api: {
      setRef,<commit_msg>ADD state for refs to be injected<commit_after>import { location } from 'global';
import {
  transformStoriesRawToStoriesHash,
  StoriesRaw,
  StoryInput,
  StoriesHash,
  isRoot,
  Story,
  Group,
  Root,
} from '../lib/stories';

import { Module } from '../index';

export interface SubState {
  refs: Record<string, InceptionRef & { data: StoriesHash } & RefState>;
}

export interface SubAPI {
  setRef: (id: string, stories: StoriesRaw) => void;
  getRefs: () => Record<RefId, RefUrl>;
}

export type Mapper = (ref: InceptionRef, story: StoryInput) => StoryInput;
export interface InceptionRef {
  id: string;
  url: string;
}
export interface RefState {
  isInjected: boolean;
}

export type RefId = string;
export type RefUrl = string;

export const getSourceType = (source: string) => {
  const { origin, pathname } = location;

  if (source === origin || source === `${origin + pathname}iframe.html`) {
    return 'local';
  }
  return 'external';
};

export const defaultMapper: Mapper = (b, a) => {
  return { ...a, kind: `${b.id}/${a.kind.replace('|', '/')}` };
};

const namespace = (input: StoriesHash, ref: InceptionRef): StoriesHash => {
  const output = {} as StoriesHash;

  Object.entries(input).forEach(([id, item]) => {
    const mappedId = `${ref.id}_${item.id}`;
    const target = output[mappedId] || ({} as Story | Group | Root);

    const addition: Partial<Story> = {
      id: mappedId,
      // this is used later to emit the correct commands over the channel
      knownAs: id,
      // this is used to know which iframe to emit the message to
      refId: ref.id,
    };

    Object.assign(target, item, addition);

    if (!isRoot(item)) {
      const mappedParentId = `${ref.id}_${item.parent}`;

      Object.assign(target, {
        parent: mappedParentId,
      });
    }

    if (item.children) {
      Object.assign(target, {
        children: item.children.map(c => `${ref.id}_${c}`),
      });
    }
    output[mappedId] = target;
  });

  return output;
};

const map = (input: StoriesRaw, ref: InceptionRef, options: { mapper?: Mapper }): StoriesRaw => {
  const output: StoriesRaw = {};
  // map the incoming stories to a prefixed, non-conflicting version
  Object.entries(input).forEach(([unmappedStoryId, unmappedStoryInput]) => {
    const mapped = options.mapper ? options.mapper(ref, unmappedStoryInput) : unmappedStoryInput;

    if (mapped) {
      output[unmappedStoryId] = mapped;
    }
  });
  return output;
};

const initRefsApi = ({ store, provider }: Module) => {
  const getRefs: SubAPI['getRefs'] = () => {
    const { refs = {} } = provider.getConfig();

    return refs;
  };

  const setRef: SubAPI['setRef'] = (id, data) => {
    const url = getRefs()[id];
    const ref = { id, url };
    const after = namespace(
      transformStoriesRawToStoriesHash(map(data, ref, { mapper: defaultMapper }), {}),
      ref
    );

    store.setState({
      refs: {
        ...(store.getState().refs || {}),
        [id]: { id, url, data: after, isInjected: true },
      },
    });
  };

  const initialState: SubState['refs'] = Object.entries(getRefs()).reduce(
    (acc, [key, value]) => ({
      ...acc,
      [key]: {
        id: key,
        url: value,
        data: {},
        isInjected: true,
      },
    }),
    {} as SubState['refs']
  );

  return {
    api: {
      setRef,
{'fraction_non_alphanumeric': 0.16311284046692606, 'fraction_numerical': 0.0, 'mean_word_length': 2.915904936014625, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 36, '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': '5689183', 'n_tokens_mistral': 2116, 'n_tokens_neox': 2094, 'n_words': 530}