Bug 1541629 - Part 2: Add a new source-actor action/reducer root type. r=jlast

Differential Revision: https://phabricator.services.mozilla.com/D27957

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Logan Smyth 2019-04-19 16:07:37 +00:00
Родитель 74f51f53d5
Коммит 59376adc13
9 изменённых файлов: 225 добавлений и 0 удалений

Просмотреть файл

@ -16,6 +16,7 @@ import * as projectTextSearch from "./project-text-search";
import * as quickOpen from "./quick-open";
import * as sourceTree from "./source-tree";
import * as sources from "./sources";
import * as sourcesActors from "./source-actors";
import * as tabs from "./tabs";
import * as debuggee from "./debuggee";
import * as toolbox from "./toolbox";
@ -27,6 +28,7 @@ export default {
...expressions,
...eventListeners,
...sources,
...sourcesActors,
...tabs,
...pause,
...ui,

Просмотреть файл

@ -22,6 +22,7 @@ CompiledModules(
'preview.js',
'project-text-search.js',
'quick-open.js',
'source-actors.js',
'source-tree.js',
'tabs.js',
'toolbox.js',

Просмотреть файл

@ -0,0 +1,32 @@
/* 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 type { ThunkArgs } from "./types";
import type { SourceActor } from "../reducers/source-actors";
export function insertSourceActor(item: SourceActor) {
return insertSourceActors([item]);
}
export function insertSourceActors(items: Array<SourceActor>) {
return function({ dispatch }: ThunkArgs) {
dispatch({
type: "INSERT_SOURCE_ACTORS",
items
});
};
}
export function removeSourceActor(item: SourceActor) {
return removeSourceActors([item]);
}
export function removeSourceActors(items: Array<SourceActor>) {
return function({ dispatch }: ThunkArgs) {
dispatch({
type: "REMOVE_SOURCE_ACTORS",
items
});
};
}

Просмотреть файл

@ -0,0 +1,20 @@
/* 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 type { SourceActor } from "../../reducers/source-actors.js";
export type SourceActorsInsertAction = {|
type: "INSERT_SOURCE_ACTORS",
items: Array<SourceActor>
|};
export type SourceActorsRemoveAction = {|
type: "REMOVE_SOURCE_ACTORS",
items: Array<SourceActor>
|};
export type SourceActorAction =
| SourceActorsInsertAction
| SourceActorsRemoveAction;

Просмотреть файл

@ -13,6 +13,7 @@ import type { SearchOperation } from "../../reducers/project-text-search";
import type { BreakpointAction } from "./BreakpointAction";
import type { SourceAction } from "./SourceAction";
import type { SourceActorAction } from "./SourceActorAction";
import type { UIAction } from "./UIAction";
import type { PauseAction } from "./PauseAction";
import type { ASTAction } from "./ASTAction";
@ -162,6 +163,7 @@ export type { ASTAction } from "./ASTAction";
export type Action =
| AddTabAction
| UpdateTabAction
| SourceActorAction
| SourceAction
| BreakpointAction
| PauseAction

Просмотреть файл

@ -10,6 +10,7 @@
*/
import expressions from "./expressions";
import sourceActors from "./source-actors";
import sources from "./sources";
import tabs from "./tabs";
import breakpoints from "./breakpoints";
@ -28,6 +29,7 @@ import eventListenerBreakpoints from "./event-listeners";
export default {
expressions,
sourceActors,
sources,
tabs,
breakpoints,

Просмотреть файл

@ -20,6 +20,7 @@ CompiledModules(
'pending-breakpoints.js',
'project-text-search.js',
'quick-open.js',
'source-actors.js',
'source-tree.js',
'sources.js',
'tabs.js',

Просмотреть файл

@ -0,0 +1,160 @@
/* 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 type { Action } from "../actions/types";
import type { SourceId, ThreadId } from "../types";
import {
createInitial,
insertResources,
removeResources,
hasResource,
getItem,
createFieldByIDGetter,
createFieldReducer,
type ResourceState,
type FieldReducer,
type FieldByIDGetter
} from "../utils/resource";
export opaque type SourceActorId = string;
export type SourceActor = {|
id: SourceActorId,
actor: string,
thread: ThreadId,
source: SourceId,
isBlackBoxed: boolean,
// The URL of the sourcemap for this source if there is one.
sourceMapURL: string | null,
// The URL of the actor itself. If the source was from an "eval" or other
// string-based source, this will not be known.
url: string | null,
// If this script was introduced by an eval, this will be the URL of the
// script that triggered the evaluation.
introductionUrl: string | null,
// The debugger's Debugger.Source API provides type information for the
// cause of this source's creation.
introductionType: string | null
|};
type SourceActorResource = {|
item: SourceActor
|};
export type SourceActorsState = ResourceState<SourceActorResource>;
export type SourceActorOuterState = { sourceActors: SourceActorsState };
const initial: SourceActorsState = createInitial({
item: {}
});
export default function update(
state: SourceActorsState = initial,
action: Action
): SourceActorsState {
switch (action.type) {
case "INSERT_SOURCE_ACTORS": {
const { items } = action;
state = insertResources(state, items.map(item => ({ item })));
break;
}
case "REMOVE_SOURCE_ACTORS": {
const { items } = action;
state = removeResources(state, items);
break;
}
}
return state;
}
// Because we are using an opaque type for our source actor IDs, these
// functions are required to convert back and forth in order to get a string
// version of the IDs. That should be super rarely used, but it means that
// we can very easily see where we're relying on the string version of IDs.
export function stringToSourceActorId(s: string): SourceActorId {
return s;
}
export function hasSourceActor(
state: SourceActorOuterState,
id: SourceActorId
): boolean {
return hasResource(state.sourceActors, id);
}
export function getSourceActor(
state: SourceActorOuterState,
id: SourceActorId
): SourceActor {
return getItem(state.sourceActors, id);
}
/**
* Get all of the source actors for a set of IDs. Caches based on the identity
* of "ids" when possible.
*/
const getSourceActorsById: FieldByIDGetter<
SourceActorResource,
"item"
> = createFieldByIDGetter("item");
export function getSourceActors(
state: SourceActorOuterState,
ids: Array<SourceActorId>
): Array<SourceActor> {
return getSourceActorsById(state.sourceActors, ids);
}
const getSourcesByThreadID: FieldReducer<
SourceActorResource,
{ [ThreadId]: Array<SourceActor> }
> = createFieldReducer(
"item",
(acc, item, id) => {
acc[item.thread] = acc[item.thread] || [];
acc[item.thread].push(item);
return acc;
},
() => ({})
);
export function getSourceActorsForThread(
state: SourceActorOuterState,
ids: ThreadId | Array<ThreadId>
): Array<SourceActor> {
const sourcesByThread = getSourcesByThreadID(state.sourceActors);
let sources = [];
for (const id of Array.isArray(ids) ? ids : [ids]) {
sources = sources.concat(sourcesByThread[id] || []);
}
return sources;
}
const getThreadsBySourceObject: FieldReducer<
SourceActorResource,
{ [SourceId]: Array<ThreadId> }
> = createFieldReducer(
"item",
(acc, item, id) => {
let sourceThreads = acc[item.source];
if (!sourceThreads) {
sourceThreads = [];
acc[item.source] = sourceThreads;
}
sourceThreads.push(item.thread);
return acc;
},
() => ({})
);
export function getThreadsBySource(
state: SourceActorOuterState
): { [SourceId]: Array<ThreadId> } {
return getThreadsBySourceObject(state.sourceActors);
}

Просмотреть файл

@ -18,6 +18,11 @@ export * from "../reducers/ast";
export * from "../reducers/project-text-search";
export * from "../reducers/source-tree";
export {
getSourceActor,
getSourceActorsForThread,
} from "../reducers/source-actors";
export {
getQuickOpenEnabled,
getQuickOpenQuery,