<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow
import queryString from 'query-string';
import {
  stringifyCommittedRanges,
  parseCommittedRanges,
} from '../profile-logic/committed-ranges';
import {
  stringifyTransforms,
  parseTransforms,
} from '../profile-logic/transforms';
import { assertExhaustiveCheck, toValidTabSlug } from '../utils/flow';
import { oneLine } from 'common-tags';
import type { UrlState } from '../types/state';
import type { DataSource } from '../types/actions';
import type { Pid } from '../types/profile';
import type { TrackIndex } from '../types/profile-derived';

export const CURRENT_URL_VERSION = 3;

function getDataSourceDirs(
  urlState: UrlState
): [] | [DataSource] | [DataSource, string] {
  const { dataSource } = urlState;
  switch (dataSource) {
    case 'from-addon':
      return ['from-addon'];
    case 'from-file':
      return ['from-file'];
    case 'local':
      return ['local', urlState.hash];
    case 'public':
      return ['public', urlState.hash];
    case 'from-url':
      return ['from-url', encodeURIComponent(urlState.profileUrl)];
    case 'compare':
      return ['compare'];
    case 'none':
      return [];
    default:
      throw assertExhaustiveCheck(dataSource);
  }
}

// "null | void" in the query objects are flags which map to true for null, and false
// for void. False flags do not show up the URL.
type BaseQuery = {|
  range?: string, //
  thread?: string, // "3"
  globalTrackOrder?: string, // "3-2-0-1"
  hiddenGlobalTracks?: string, // "0-1"
  hiddenLocalTracksByPid?: string,
  localTrackOrderByPid?: string,
  file?: string, // Path into a zip file.
  react_perf?: null, // Flag to activate react's UserTimings profiler.
  transforms?: string,
  timelineType?: string,
  // The following values are legacy, and will be converted to track-based values. These
  // value can't be upgraded using the typical URL upgrading process, as the full profile
  // must be fetched to compute the tracks.
  threadOrder?: string, // "3-2-0-1"
  hiddenThreads?: string, // "0-1"
  profiles?: string[],
|};

type CallTreeQuery = {|
  ...BaseQuery,
  search?: string, // "js::RunScript"
  invertCallstack?: null | void,
  implementation?: string,
|};

type MarkersQuery = {|
  ...BaseQuery,
  markerSearch?: string, // "DOMEvent"
|};

type StackChartQuery = {|
  ...BaseQuery,
  search?: string, // "js::RunScript"
  invertCallstack?: null | void,
  implementation?: string,
|};

type JsTracerQuery = {|
  ...BaseQuery,
  summary?: null | void,
|};

// Use object type spread in the definition of Query rather than unions, so that they
// are really easy to manipulate. This permissive definition makes it easy to not have
// to refine the type down to the individual query types when working with them.
type Query = {
  ...CallTreeQuery,
  ...MarkersQuery,
  ...StackChartQuery,
  ...JsTracerQuery,
};

type UrlObject = {|
  pathParts: string[],
  query: Query,
|};<commit_msg>Refine the XXXQUery types in url-handling.js (PR #1834)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow
import queryString from 'query-string';
import {
  stringifyCommittedRanges,
  parseCommittedRanges,
} from '../profile-logic/committed-ranges';
import {
  stringifyTransforms,
  parseTransforms,
} from '../profile-logic/transforms';
import { assertExhaustiveCheck, toValidTabSlug } from '../utils/flow';
import { oneLine } from 'common-tags';
import type { UrlState } from '../types/state';
import type { DataSource } from '../types/actions';
import type { Pid } from '../types/profile';
import type { TrackIndex } from '../types/profile-derived';

export const CURRENT_URL_VERSION = 3;

function getDataSourceDirs(
  urlState: UrlState
): [] | [DataSource] | [DataSource, string] {
  const { dataSource } = urlState;
  switch (dataSource) {
    case 'from-addon':
      return ['from-addon'];
    case 'from-file':
      return ['from-file'];
    case 'local':
      return ['local', urlState.hash];
    case 'public':
      return ['public', urlState.hash];
    case 'from-url':
      return ['from-url', encodeURIComponent(urlState.profileUrl)];
    case 'compare':
      return ['compare'];
    case 'none':
      return [];
    default:
      throw assertExhaustiveCheck(dataSource);
  }
}

// "null | void" in the query objects are flags which map to true for null, and false
// for void. False flags do not show up the URL.
type BaseQuery = {|
  range: string, //
  thread: string, // "3"
  globalTrackOrder: string, // "3-2-0-1"
  hiddenGlobalTracks: string, // "0-1"
  hiddenLocalTracksByPid: string,
  localTrackOrderByPid: string,
  file: string, // Path into a zip file.
  transforms: string,
  timelineType: string,
  // The following values are legacy, and will be converted to track-based values. These
  // value can't be upgraded using the typical URL upgrading process, as the full profile
  // must be fetched to compute the tracks.
  threadOrder: string, // "3-2-0-1"
  hiddenThreads: string, // "0-1"
  profiles: string[],
|};

type CallTreeQuery = {|
  ...BaseQuery,
  search: string, // "js::RunScript"
  invertCallstack: null | void,
  implementation: string,
|};

type MarkersQuery = {|
  ...BaseQuery,
  markerSearch: string, // "DOMEvent"
|};

type StackChartQuery = {|
  ...BaseQuery,
  search: string, // "js::RunScript"
  invertCallstack: null | void,
  implementation: string,
|};

type JsTracerQuery = {|
  ...BaseQuery,
  summary: null | void,
|};

// Use object type spread in the definition of Query rather than unions, so that they
// are really easy to manipulate. This permissive definition makes it easy to not have
// to refine the type down to the individual query types when working with them.
type Query = {|
  ...CallTreeQuery,
  ...MarkersQuery,
  ...StackChartQuery,
  ...JsTracerQuery,
|};

type UrlObject = {|
  pathParts: string[],
  query: $Shape<Query>,
|};
{'fraction_non_alphanumeric': 0.1370281124497992, 'fraction_numerical': 0.00642570281124498, 'mean_word_length': 3.396892655367232, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, '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': '4866460', 'n_tokens_mistral': 1954, 'n_tokens_neox': 1916, 'n_words': 641}