From 8d0a2dd0ed2a0245e7b0ebdcbb3644fa562357c8 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Fri, 5 Apr 2019 02:41:39 +0200 Subject: [PATCH 1/3] [scheduler] Add tracing module --- types/scheduler/index.d.ts | 1 + types/scheduler/tracing-tests.ts | 42 +++++++++++++++ types/scheduler/tracing.d.ts | 93 ++++++++++++++++++++++++++++++++ types/scheduler/tsconfig.json | 4 +- 4 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 types/scheduler/tracing-tests.ts create mode 100644 types/scheduler/tracing.d.ts diff --git a/types/scheduler/index.d.ts b/types/scheduler/index.d.ts index 15644f5ae4..dd917b95f6 100644 --- a/types/scheduler/index.d.ts +++ b/types/scheduler/index.d.ts @@ -1,6 +1,7 @@ // Type definitions for scheduler 0.12 // Project: https://reactjs.org/ // Definitions by: Nathan Bierema +// Sebastian Silbermann // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.1 diff --git a/types/scheduler/tracing-tests.ts b/types/scheduler/tracing-tests.ts new file mode 100644 index 0000000000..91a8a4f6b8 --- /dev/null +++ b/types/scheduler/tracing-tests.ts @@ -0,0 +1,42 @@ +import { + __subscriberRef, + __interactionsRef, + unstable_clear as clear, + unstable_getCurrent as getCurrent, + unstable_getThreadID as getThreadID, + unstable_trace as trace, + unstable_wrap as wrap, + WrappedFunction +} from "scheduler/tracing"; + +// it should return the value of a traced function +// $ExpectType number +trace("initial render", Date.now(), () => 123); + +const fn = (n: number, s: string) => s.repeat(n); +let wrapped: WrappedFunction | undefined; +trace("arbitrary", 0, () => { + wrapped = wrap(fn); +}); +if (wrapped !== undefined) { + // it should pass arguments through and return the value of a wrapped function + // $ExpectType string + wrapped(3, "w"); +} + +// it should return the value of a wrapped function +// $ExpectType number +clear(() => 123); + +// $ExpectType Set | null +getCurrent(); + +// it should return a unique threadID +// $ExpectType number +getThreadID(); + +// should expose the current set of interactions to be externally manipulated +const isAssignable = __interactionsRef.current === getCurrent()!; + +// should expose a subscriber ref to be externally manipulated +__subscriberRef.current = null; diff --git a/types/scheduler/tracing.d.ts b/types/scheduler/tracing.d.ts new file mode 100644 index 0000000000..f062e236d5 --- /dev/null +++ b/types/scheduler/tracing.d.ts @@ -0,0 +1,93 @@ +export interface Interaction { + __count: number; + id: number; + name: string; + timestamp: number; +} + +export interface Subscriber { + /** + * A new interaction has been created via the trace() method. + */ + onInteractionTraced: (interaction: Interaction) => void; + + /** + * All scheduled async work for an interaction has finished. + */ + onInteractionScheduledWorkCompleted: (interaction: Interaction) => void; + + /** + * New async work has been scheduled for a set of interactions. + * When this work is later run, onWorkStarted/onWorkStopped will be called. + * A batch of async/yieldy work may be scheduled multiple times before completing. + * In that case, onWorkScheduled may be called more than once before onWorkStopped. + * Work is scheduled by a "thread" which is identified by a unique ID. + */ + onWorkScheduled: (interactions: Set, threadID: number) => void; + + /** + * A batch of scheduled work has been canceled. + * Work is done by a "thread" which is identified by a unique ID. + */ + onWorkCanceled: (interactions: Set, threadID: number) => void; + + /** + * A batch of work has started for a set of interactions. + * When this work is complete, onWorkStopped will be called. + * Work is not always completed synchronously; yielding may occur in between. + * A batch of async/yieldy work may also be re-started before completing. + * In that case, onWorkStarted may be called more than once before onWorkStopped. + * Work is done by a "thread" which is identified by a unique ID. + */ + onWorkStarted: (interactions: Set, threadID: number) => void; + + /** + * A batch of work has completed for a set of interactions. + * Work is done by a "thread" which is identified by a unique ID. + */ + onWorkStopped: (interactions: Set, threadID: number) => void; +} + +export interface InteractionsRef { + current: Set; +} + +export interface SubscriberRef { + current: Subscriber | null; +} + +export const __interactionsRef: InteractionsRef; +export const __subscriberRef: SubscriberRef; + +export function unstable_clear(callback: () => T): T; + +export function unstable_getCurrent(): Set | null; + +export function unstable_getThreadID(): number; + +export function unstable_trace( + name: string, + timestamp: number, + callback: () => T, + threadID?: number +): T; + +export type WrappedFunction any> = T & { + cancel: () => void; +}; + +/** + * The callback is immediately returned if the enableSchedulerTracing is disabled. + * It is unclear for which bundles this is the case. + * + * @param callback + * @param threadID + */ +export function unstable_wrap any>( + callback: T, + threadID?: number +): WrappedFunction; + +export function unstable_subscribe(subscriber: Subscriber): void; + +export function unstable_unsubscribe(subscriber: Subscriber): void; diff --git a/types/scheduler/tsconfig.json b/types/scheduler/tsconfig.json index b6c5c6021a..629f1fc5db 100644 --- a/types/scheduler/tsconfig.json +++ b/types/scheduler/tsconfig.json @@ -18,6 +18,8 @@ }, "files": [ "index.d.ts", - "scheduler-tests.ts" + "scheduler-tests.ts", + "tracing.d.ts", + "tracing-tests.ts" ] } From ece47d0ee8cb832cce77e83887aabffbdc741acb Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Sat, 6 Apr 2019 02:16:19 +0200 Subject: [PATCH 2/3] fix types publisher error --- types/scheduler/{scheduler-tests.ts => test/scheduler.ts} | 0 types/scheduler/{tracing-tests.ts => test/tracing.ts} | 0 types/scheduler/tsconfig.json | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename types/scheduler/{scheduler-tests.ts => test/scheduler.ts} (100%) rename types/scheduler/{tracing-tests.ts => test/tracing.ts} (100%) diff --git a/types/scheduler/scheduler-tests.ts b/types/scheduler/test/scheduler.ts similarity index 100% rename from types/scheduler/scheduler-tests.ts rename to types/scheduler/test/scheduler.ts diff --git a/types/scheduler/tracing-tests.ts b/types/scheduler/test/tracing.ts similarity index 100% rename from types/scheduler/tracing-tests.ts rename to types/scheduler/test/tracing.ts diff --git a/types/scheduler/tsconfig.json b/types/scheduler/tsconfig.json index 629f1fc5db..8e098a5df3 100644 --- a/types/scheduler/tsconfig.json +++ b/types/scheduler/tsconfig.json @@ -18,8 +18,8 @@ }, "files": [ "index.d.ts", - "scheduler-tests.ts", + "test/scheduler.ts", "tracing.d.ts", - "tracing-tests.ts" + "test/tracing.ts" ] } From 0f72fc142b2c8c14c9246173c28219a24e14810e Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Sun, 7 Apr 2019 17:49:58 +0200 Subject: [PATCH 3/3] [scheduler] Add augmentable interface to declare the used build --- types/scheduler/index.d.ts | 2 +- types/scheduler/test/tracing.ts | 6 ++--- types/scheduler/tracing.d.ts | 44 ++++++++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/types/scheduler/index.d.ts b/types/scheduler/index.d.ts index dd917b95f6..432cc06061 100644 --- a/types/scheduler/index.d.ts +++ b/types/scheduler/index.d.ts @@ -3,7 +3,7 @@ // Definitions by: Nathan Bierema // Sebastian Silbermann // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.1 +// TypeScript Version: 2.8 export type FrameCallbackType = () => FrameCallbackType | void; export interface CallbackNode { diff --git a/types/scheduler/test/tracing.ts b/types/scheduler/test/tracing.ts index 91a8a4f6b8..83dfdaec0f 100644 --- a/types/scheduler/test/tracing.ts +++ b/types/scheduler/test/tracing.ts @@ -14,7 +14,7 @@ import { trace("initial render", Date.now(), () => 123); const fn = (n: number, s: string) => s.repeat(n); -let wrapped: WrappedFunction | undefined; +let wrapped: WrappedFunction | typeof fn | undefined; trace("arbitrary", 0, () => { wrapped = wrap(fn); }); @@ -36,7 +36,7 @@ getCurrent(); getThreadID(); // should expose the current set of interactions to be externally manipulated -const isAssignable = __interactionsRef.current === getCurrent()!; +const isAssignable = __interactionsRef!.current === getCurrent()!; // should expose a subscriber ref to be externally manipulated -__subscriberRef.current = null; +__subscriberRef!.current = null; diff --git a/types/scheduler/tracing.d.ts b/types/scheduler/tracing.d.ts index f062e236d5..2105336867 100644 --- a/types/scheduler/tracing.d.ts +++ b/types/scheduler/tracing.d.ts @@ -1,3 +1,41 @@ +// disable automatic export +export {}; +/** + * This type is only interesting if you're only using this module for a specifc build environment. + * + * With module augmentation you can declare what build of scheduler you are using by + * augmenting this interface with e.g. `interface Build { type: 'development'; }` + * Depending on the build some exported members have different types. + * Possible values are `production`, `profiling` and `development`. + * The default behavior for the types is to use a union of all possible types. + */ +// tslint:disable-next-line: no-empty-interface +export interface Build {} + +export type EnableSchedulerTracing = Build extends { type: infer BuildType } + ? BuildType extends "production" | "profiling" + ? false + : BuildType extends "development" + ? true + : undefined + : undefined; + +type TypeByBuildFlag< + Flag extends boolean | undefined, + WhenTrue, + WhenFalse +> = Flag extends undefined + ? (WhenTrue | WhenFalse) + : Flag extends true + ? WhenTrue + : WhenFalse; + +type IfSchedulerTracing = TypeByBuildFlag< + EnableSchedulerTracing, + WhenTrue, + WhenFalse +>; + export interface Interaction { __count: number; id: number; @@ -56,8 +94,8 @@ export interface SubscriberRef { current: Subscriber | null; } -export const __interactionsRef: InteractionsRef; -export const __subscriberRef: SubscriberRef; +export const __interactionsRef: IfSchedulerTracing; +export const __subscriberRef: IfSchedulerTracing; export function unstable_clear(callback: () => T): T; @@ -86,7 +124,7 @@ export type WrappedFunction any> = T & { export function unstable_wrap any>( callback: T, threadID?: number -): WrappedFunction; +): IfSchedulerTracing, T>; export function unstable_subscribe(subscriber: Subscriber): void;