close
Skip to content
This repository was archived by the owner on May 25, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<al-hover-demo-form ([useOnPush])="useOnPush">
<al-hover-demo-form [(useOnPush)]="useOnPush">
</al-hover-demo-form>

<al-hover-demo-value [useOnPush]="useOnPush">
Expand Down
21 changes: 8 additions & 13 deletions packages/core/src/augury-core.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { ChannelManager } from './channels';
import { AuguryEventAssembler, ChannelManager } from './channels';
import { HistoryManager } from './history';
import { PluginManager } from './plugins';
import { Plugin } from './plugins';
import { Probe, ProbeManager } from './probes';
import { Reducer } from './reducers';
import { Scanner } from './scanner';
import { AuguryEventProjection } from './projections';

export class AuguryCore {
public readonly historyManager: HistoryManager;
Expand All @@ -17,18 +16,14 @@ export class AuguryCore {
this.channelManager = new ChannelManager();
this.historyManager = new HistoryManager();
this.pluginManager = new PluginManager(plugins, this);

this.probeManager.subscribe(event => {
event.markComplete();

this.historyManager.addEvent(event);
});
this.probeManager.subscribe(event => this.historyManager.addEvent(event));
}

public createLiveChannel(reducer: Reducer) {
const scanner = new Scanner(reducer, this.historyManager);
scanner.scan(this.probeManager);
public createSimpleChannel(projection: AuguryEventProjection<any>) {
return this.channelManager.createSimpleChannel(this.probeManager, projection);
}

return this.channelManager.createScannerChannel(scanner);
public createAssemblyChannel(assembler: AuguryEventAssembler<any>) {
return this.channelManager.createAssemblyChannel(this.probeManager, assembler);
}
}
4 changes: 4 additions & 0 deletions packages/core/src/channels/assemblers/assembler.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface Assembler<Input, Output> {
process(input: Input): boolean;
finish(): Output | null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { AuguryEvent } from '../../events';
import { Assembler } from './assembler.interface';

export abstract class AuguryEventAssembler<Output> implements Assembler<AuguryEvent, Output> {
public abstract process(event: AuguryEvent): boolean;

public finish(): Output | null {
const output = this.getOutput();

this.cleanup();

return output;
}

protected abstract getOutput(): Output | null;

protected abstract cleanup();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { AuguryEvent } from '../../../events';
import { AuguryEventAssembler } from '../augury-event-assembler.class';
import { ChangeDetectionInfo } from './change-detection-info.interface';

export class ChangeDetectionInfoAssembler extends AuguryEventAssembler<ChangeDetectionInfo> {
private changeDetectionInfo: Partial<ChangeDetectionInfo> = {
drag: 0,
};
private numberOfViewChecks: number = 0;

public process(event: AuguryEvent): boolean {
if (event.probeName === 'ComponentHooksProbe') {
this.changeDetectionInfo.drag += event.getAuguryDrag();

switch (event.payload.hook) {
case 'ngDoCheck':
if (!this.changeDetectionInfo.componentsChecked) {
this.changeDetectionInfo = {
...this.changeDetectionInfo,
startEventId: event.id,
startTimestamp: event.creationAtTimestamp,
componentsChecked: [],
};
}

this.changeDetectionInfo.componentsChecked.push(event.payload.componentInstance);

break;
case 'ngAfterViewChecked':
this.numberOfViewChecks++;

this.changeDetectionInfo = {
...this.changeDetectionInfo,
endEventId: event.id,
endTimestamp: event.completedAtTimestamp,
};

if (this.numberOfViewChecks === this.changeDetectionInfo.componentsChecked.length) {
return true;
}
}
}

return false;
}

protected getOutput(): ChangeDetectionInfo | null {
return this.changeDetectionInfo as ChangeDetectionInfo;
}

protected cleanup() {
this.changeDetectionInfo = {
drag: 0,
};
this.numberOfViewChecks = 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface ChangeDetectionInfo {
startEventId: number;
startTimestamp: number;
endEventId: number;
endTimestamp: number;
componentsChecked: any[];
drag: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './change-detection-info.interface';
export * from './change-detection-info-assembler.class';
5 changes: 5 additions & 0 deletions packages/core/src/channels/assemblers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './augury-event-assembler.class';
export * from './assembler.interface';
export * from './change-detection-info';
export * from './instability-period-info';
export * from './task-info';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './instability-period-info.interface';
export * from './instability-period-info-assembler.class';
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { AuguryEvent } from '../../../events';
import { AuguryEventAssembler } from '../augury-event-assembler.class';
import { InstabilityPeriodInfo } from './instability-period-info.interface';

export class InstabilityPeriodInfoAssembler extends AuguryEventAssembler<InstabilityPeriodInfo> {
private instabilityPeriodInfo: Partial<InstabilityPeriodInfo> = {};
private isDuringInstabilityPeriod = false;

public process(event: AuguryEvent): boolean {
if (event.name === 'onUnstable') {
this.instabilityPeriodInfo = {
startEventId: event.id,
startTimestamp: event.creationAtTimestamp,
drag: 0,
};

this.isDuringInstabilityPeriod = true;
}

if (this.isDuringInstabilityPeriod) {
this.instabilityPeriodInfo.drag = event.getAuguryDrag();

if (event.name === 'onStable') {
this.instabilityPeriodInfo = {
...this.instabilityPeriodInfo,
endEventId: event.id,
endTimestamp: event.creationAtTimestamp,
componentTree: event.payload.componentTree,
};

return true;
}
}

return false;
}

protected getOutput(): InstabilityPeriodInfo {
return this.instabilityPeriodInfo as InstabilityPeriodInfo;
}

protected cleanup() {
this.instabilityPeriodInfo = {};
this.isDuringInstabilityPeriod = false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface InstabilityPeriodInfo {
componentTree: any[];
startEventId: number;
startTimestamp: number;
endEventId: number;
endTimestamp: number;
drag: number;
}
3 changes: 3 additions & 0 deletions packages/core/src/channels/assemblers/task-info/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './task-info.interface';
export * from './root-task-info-assembler.class';
export * from './ng-task-info-assembler.class';
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { TaskInfoAssembler } from './task-info.class';

export class NgTaskInfoAssembler extends TaskInfoAssembler {
protected getExecutingEventName(): string {
return 'onInvokeTask_executing';
}

protected getCompletedEventName(): string {
return 'onInvokeTask_completed';
}

protected getZoneValue(): string {
return 'ng';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { TaskInfoAssembler } from './task-info.class';

export class RootTaskInfoAssembler extends TaskInfoAssembler {
protected getExecutingEventName(): string {
return 'root_task_executing';
}

protected getCompletedEventName(): string {
return 'root_task_completed';
}

protected getZoneValue(): string {
return 'root';
}
}
52 changes: 52 additions & 0 deletions packages/core/src/channels/assemblers/task-info/task-info.class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { AuguryEvent } from '../../../events';
import { AuguryEventAssembler } from '../augury-event-assembler.class';
import { TaskInfo } from './task-info.interface';

export abstract class TaskInfoAssembler extends AuguryEventAssembler<TaskInfo> {
private taskInfo: Partial<TaskInfo> = {};
private isTaskExecuting = false;

public process(event: AuguryEvent): boolean {
if (event.name === this.getExecutingEventName()) {
this.taskInfo = {
zone: this.getZoneValue(),
task: event.payload.task,
startEventId: event.id,
startTimestamp: event.creationAtTimestamp,
drag: 0,
};

this.isTaskExecuting = true;
}

if (this.isTaskExecuting) {
this.taskInfo.drag += event.getAuguryDrag();

if (event.name === this.getCompletedEventName()) {
this.taskInfo = {
...this.taskInfo,
endTimestamp: event.creationAtTimestamp,
};

return true;
}
}

return false;
}

protected getOutput(): TaskInfo {
return this.taskInfo as TaskInfo;
}

protected cleanup() {
this.taskInfo = {};
this.isTaskExecuting = false;
}

protected abstract getExecutingEventName(): string;

protected abstract getCompletedEventName(): string;

protected abstract getZoneValue(): string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface TaskInfo {
zone: string;
task: any; // ZoneTask
startEventId: number;
startTimestamp: number;
endTimestamp: number;
drag: number;
}
29 changes: 29 additions & 0 deletions packages/core/src/channels/assembly-channel.class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Subscription } from '../event-emitters';
import { ProbeManager } from '../probes';
import { AuguryEventAssembler } from './assemblers';
import { ChannelManager } from './channel-manager.class';
import { Channel } from './channel.class';

export class AssemblyChannel<Output> extends Channel<Output> {
constructor(
manager: ChannelManager,
private probeManager: ProbeManager,
private assembler: AuguryEventAssembler<Output>,
) {
super(manager);
}

public subscribe(handleOutput: (output: Output) => void): Subscription {
return this.probeManager.subscribe(event => {
const isDone = this.assembler.process(event);

if (isDone) {
const output = this.assembler.finish();

if (output) {
handleOutput(output);
}
}
});
}
}
31 changes: 23 additions & 8 deletions packages/core/src/channels/channel-manager.class.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
import { Scanner } from '../scanner';
import { ProbeManager } from '../probes';
import { AuguryEventProjection } from '../projections';
import { AuguryEventAssembler } from './assemblers';
import { AssemblyChannel } from './assembly-channel.class';
import { Channel } from './channel.class';
import { ScannerChannel } from './scanner-channel.class';
import { ProbeChannel } from './probe-channel.class';

export class ChannelManager {
private channels: Array<Channel<any>> = [];

public createScannerChannel(scanner: Scanner): Channel<any> {
const channel = new ScannerChannel<any>(scanner, this);

this.channels.push(channel);
public createSimpleChannel(
probeManager: ProbeManager,
projection: AuguryEventProjection<any>,
): Channel<any> {
return this.addChannel(new ProbeChannel(this, probeManager, projection));
}

return channel;
public createAssemblyChannel(
probeManager: ProbeManager,
assembler: AuguryEventAssembler<any>,
): Channel<any> {
return this.addChannel(new AssemblyChannel(this, probeManager, assembler));
}

public releaseDeadChannel(channelToRelease: Channel<any>) {
public removeChannel(channelToRelease: Channel<any>) {
this.channels = this.channels.filter(channel => channel !== channelToRelease);
}

private addChannel(channel: Channel<any>): Channel<any> {
this.channels.push(channel);

return channel;
}
}
12 changes: 8 additions & 4 deletions packages/core/src/channels/channel.class.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Subscription } from '../event-emitters';
import { ChannelManager } from './channel-manager.class';

export abstract class Channel<EventType> {
protected constructor(public readonly type: string) {}
export abstract class Channel<Output> {
protected constructor(private readonly manager: ChannelManager) {}

public abstract subscribe(handleEvent: (event: EventType) => void): Subscription;
public abstract shutdown(): void;
public abstract subscribe(handleOutput: (output: Output) => void): Subscription;

public shutdown(): void {
this.manager.removeChannel(this);
}
}
2 changes: 1 addition & 1 deletion packages/core/src/channels/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './channel.class';
export * from './channel-manager.class';
export * from './scanner-channel.class';
export * from './assemblers';
Loading