summaryrefslogtreecommitdiff
path: root/cli/js/web
diff options
context:
space:
mode:
Diffstat (limited to 'cli/js/web')
-rw-r--r--cli/js/web/performance.ts332
-rw-r--r--cli/js/web/streams/internals.ts8
-rw-r--r--cli/js/web/streams/queuing_strategy.ts2
-rw-r--r--cli/js/web/streams/readable_byte_stream_controller.ts2
-rw-r--r--cli/js/web/streams/readable_stream.ts2
-rw-r--r--cli/js/web/streams/readable_stream_default_controller.ts2
-rw-r--r--cli/js/web/streams/readable_stream_default_reader.ts2
-rw-r--r--cli/js/web/streams/transform_stream.ts2
-rw-r--r--cli/js/web/streams/transform_stream_default_controller.ts2
-rw-r--r--cli/js/web/streams/writable_stream.ts2
-rw-r--r--cli/js/web/streams/writable_stream_default_controller.ts2
-rw-r--r--cli/js/web/streams/writable_stream_default_writer.ts2
-rw-r--r--cli/js/web/util.ts8
13 files changed, 348 insertions, 20 deletions
diff --git a/cli/js/web/performance.ts b/cli/js/web/performance.ts
index 67f8f1b6c..eb0479b37 100644
--- a/cli/js/web/performance.ts
+++ b/cli/js/web/performance.ts
@@ -1,10 +1,336 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { now as opNow } from "../ops/timers.ts";
+import { customInspect, inspect } from "./console.ts";
+import { cloneValue, setFunctionName } from "./util.ts";
+
+let performanceEntries: PerformanceEntryList = [];
+
+function findMostRecent(
+ name: string,
+ type: "mark" | "measure"
+): PerformanceEntry | undefined {
+ return performanceEntries
+ .slice()
+ .reverse()
+ .find((entry) => entry.name === name && entry.entryType === type);
+}
+
+function convertMarkToTimestamp(mark: string | number): number {
+ if (typeof mark === "string") {
+ const entry = findMostRecent(mark, "mark");
+ if (!entry) {
+ throw new SyntaxError(`Cannot find mark: "${mark}".`);
+ }
+ return entry.startTime;
+ }
+ if (mark < 0) {
+ throw new TypeError("Mark cannot be negative.");
+ }
+ return mark;
+}
+
+function filterByNameType(
+ name?: string,
+ type?: "mark" | "measure"
+): PerformanceEntryList {
+ return performanceEntries.filter(
+ (entry) =>
+ (name ? entry.name === name : true) &&
+ (type ? entry.entryType === type : true)
+ );
+}
+
+function now(): number {
+ const res = opNow();
+ return res.seconds * 1e3 + res.subsecNanos / 1e6;
+}
+
+export class PerformanceEntryImpl implements PerformanceEntry {
+ #name: string;
+ #entryType: string;
+ #startTime: number;
+ #duration: number;
+
+ get name(): string {
+ return this.#name;
+ }
+
+ get entryType(): string {
+ return this.#entryType;
+ }
+
+ get startTime(): number {
+ return this.#startTime;
+ }
+
+ get duration(): number {
+ return this.#duration;
+ }
+
+ constructor(
+ name: string,
+ entryType: string,
+ startTime: number,
+ duration: number
+ ) {
+ this.#name = name;
+ this.#entryType = entryType;
+ this.#startTime = startTime;
+ this.#duration = duration;
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ toJSON(): any {
+ return {
+ name: this.#name,
+ entryType: this.#entryType,
+ startTime: this.#startTime,
+ duration: this.#duration,
+ };
+ }
+
+ [customInspect](): string {
+ return `${this.constructor.name} { name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`;
+ }
+}
+
+export class PerformanceMarkImpl extends PerformanceEntryImpl
+ implements PerformanceMark {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ #detail: any;
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ get detail(): any {
+ return this.#detail;
+ }
+
+ get entryType(): "mark" {
+ return "mark";
+ }
+
+ constructor(
+ name: string,
+ { detail = null, startTime = now() }: PerformanceMarkOptions = {}
+ ) {
+ super(name, "mark", startTime, 0);
+ if (startTime < 0) {
+ throw new TypeError("startTime cannot be negative");
+ }
+ this.#detail = cloneValue(detail);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ toJSON(): any {
+ return {
+ name: this.name,
+ entryType: this.entryType,
+ startTime: this.startTime,
+ duration: this.duration,
+ detail: this.detail,
+ };
+ }
+
+ [customInspect](): string {
+ return this.detail
+ ? `${this.constructor.name} {\n detail: ${inspect(this.detail, {
+ depth: 3,
+ })},\n name: "${this.name}",\n entryType: "${
+ this.entryType
+ }",\n startTime: ${this.startTime},\n duration: ${this.duration}\n}`
+ : `${this.constructor.name} { detail: ${this.detail}, name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`;
+ }
+}
+
+export class PerformanceMeasureImpl extends PerformanceEntryImpl
+ implements PerformanceMeasure {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ #detail: any;
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ get detail(): any {
+ return this.#detail;
+ }
+
+ get entryType(): "measure" {
+ return "measure";
+ }
+
+ constructor(
+ name: string,
+ startTime: number,
+ duration: number,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ detail: any = null
+ ) {
+ super(name, "measure", startTime, duration);
+ this.#detail = cloneValue(detail);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ toJSON(): any {
+ return {
+ name: this.name,
+ entryType: this.entryType,
+ startTime: this.startTime,
+ duration: this.duration,
+ detail: this.detail,
+ };
+ }
+
+ [customInspect](): string {
+ return this.detail
+ ? `${this.constructor.name} {\n detail: ${inspect(this.detail, {
+ depth: 3,
+ })},\n name: "${this.name}",\n entryType: "${
+ this.entryType
+ }",\n startTime: ${this.startTime},\n duration: ${this.duration}\n}`
+ : `${this.constructor.name} { detail: ${this.detail}, name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`;
+ }
+}
+
+export class PerformanceImpl implements Performance {
+ clearMarks(markName?: string): void {
+ if (markName == null) {
+ performanceEntries = performanceEntries.filter(
+ (entry) => entry.entryType !== "mark"
+ );
+ } else {
+ performanceEntries = performanceEntries.filter(
+ (entry) => !(entry.name === markName && entry.entryType === "mark")
+ );
+ }
+ }
+
+ clearMeasures(measureName?: string): void {
+ if (measureName == null) {
+ performanceEntries = performanceEntries.filter(
+ (entry) => entry.entryType !== "measure"
+ );
+ } else {
+ performanceEntries = performanceEntries.filter(
+ (entry) =>
+ !(entry.name === measureName && entry.entryType === "measure")
+ );
+ }
+ }
+
+ getEntries(): PerformanceEntryList {
+ return filterByNameType();
+ }
+ getEntriesByName(
+ name: string,
+ type?: "mark" | "measure"
+ ): PerformanceEntryList {
+ return filterByNameType(name, type);
+ }
+ getEntriesByType(type: "mark" | "measure"): PerformanceEntryList {
+ return filterByNameType(undefined, type);
+ }
+
+ mark(
+ markName: string,
+ options: PerformanceMarkOptions = {}
+ ): PerformanceMark {
+ // 3.1.1.1 If the global object is a Window object and markName uses the
+ // same name as a read only attribute in the PerformanceTiming interface,
+ // throw a SyntaxError. - not implemented
+ const entry = new PerformanceMarkImpl(markName, options);
+ // 3.1.1.7 Queue entry - not implemented
+ performanceEntries.push(entry);
+ return entry;
+ }
+
+ measure(
+ measureName: string,
+ options?: PerformanceMeasureOptions
+ ): PerformanceMeasure;
+ measure(
+ measureName: string,
+ startMark?: string,
+ endMark?: string
+ ): PerformanceMeasure;
+ measure(
+ measureName: string,
+ startOrMeasureOptions: string | PerformanceMeasureOptions = {},
+ endMark?: string
+ ): PerformanceMeasure {
+ if (startOrMeasureOptions && typeof startOrMeasureOptions === "object") {
+ if (endMark) {
+ throw new TypeError("Options cannot be passed with endMark.");
+ }
+ if (
+ !("start" in startOrMeasureOptions) &&
+ !("end" in startOrMeasureOptions)
+ ) {
+ throw new TypeError("A start or end mark must be supplied in options.");
+ }
+ if (
+ "start" in startOrMeasureOptions &&
+ "duration" in startOrMeasureOptions &&
+ "end" in startOrMeasureOptions
+ ) {
+ throw new TypeError(
+ "Cannot specify start, end, and duration together in options."
+ );
+ }
+ }
+ let endTime: number;
+ if (endMark) {
+ endTime = convertMarkToTimestamp(endMark);
+ } else if (
+ typeof startOrMeasureOptions === "object" &&
+ "end" in startOrMeasureOptions
+ ) {
+ endTime = convertMarkToTimestamp(startOrMeasureOptions.end!);
+ } else if (
+ typeof startOrMeasureOptions === "object" &&
+ "start" in startOrMeasureOptions &&
+ "duration" in startOrMeasureOptions
+ ) {
+ const start = convertMarkToTimestamp(startOrMeasureOptions.start!);
+ const duration = convertMarkToTimestamp(startOrMeasureOptions.duration!);
+ endTime = start + duration;
+ } else {
+ endTime = now();
+ }
+ let startTime: number;
+ if (
+ typeof startOrMeasureOptions === "object" &&
+ "start" in startOrMeasureOptions
+ ) {
+ startTime = convertMarkToTimestamp(startOrMeasureOptions.start!);
+ } else if (
+ typeof startOrMeasureOptions === "object" &&
+ "end" in startOrMeasureOptions &&
+ "duration" in startOrMeasureOptions
+ ) {
+ const end = convertMarkToTimestamp(startOrMeasureOptions.end!);
+ const duration = convertMarkToTimestamp(startOrMeasureOptions.duration!);
+ startTime = end - duration;
+ } else if (typeof startOrMeasureOptions === "string") {
+ startTime = convertMarkToTimestamp(startOrMeasureOptions);
+ } else {
+ startTime = 0;
+ }
+ const entry = new PerformanceMeasureImpl(
+ measureName,
+ startTime,
+ endTime - startTime,
+ typeof startOrMeasureOptions === "object"
+ ? startOrMeasureOptions.detail ?? null
+ : null
+ );
+ performanceEntries.push(entry);
+ return entry;
+ }
-export class Performance {
now(): number {
- const res = opNow();
- return res.seconds * 1e3 + res.subsecNanos / 1e6;
+ return now();
}
}
+
+setFunctionName(PerformanceEntryImpl, "PerformanceEntry");
+setFunctionName(PerformanceMarkImpl, "PerformanceMark");
+setFunctionName(PerformanceMeasureImpl, "PerformanceMeasure");
+setFunctionName(PerformanceImpl, "Performance");
diff --git a/cli/js/web/streams/internals.ts b/cli/js/web/streams/internals.ts
index f6b20ccaf..58a62e3cb 100644
--- a/cli/js/web/streams/internals.ts
+++ b/cli/js/web/streams/internals.ts
@@ -19,7 +19,7 @@ import { WritableStreamDefaultWriterImpl } from "./writable_stream_default_write
import { WritableStreamImpl } from "./writable_stream.ts";
import { AbortSignalImpl } from "../abort_signal.ts";
import { DOMExceptionImpl as DOMException } from "../dom_exception.ts";
-import { cloneValue } from "../util.ts";
+import { cloneValue, setFunctionName } from "../util.ts";
import { assert, AssertionError } from "../../util.ts";
export type AbortAlgorithm = (reason?: any) => PromiseLike<void>;
@@ -1320,12 +1320,6 @@ export function resetQueue<R>(container: Container<R>): void {
container[sym.queueTotalSize] = 0;
}
-/** An internal function which provides a function name for some generated
- * functions, so stack traces are a bit more readable. */
-export function setFunctionName(fn: Function, value: string): void {
- Object.defineProperty(fn, "name", { value, configurable: true });
-}
-
/** An internal function which mimics the behavior of setting the promise to
* handled in JavaScript. In this situation, an assertion failure, which
* shouldn't happen will get thrown, instead of swallowed. */
diff --git a/cli/js/web/streams/queuing_strategy.ts b/cli/js/web/streams/queuing_strategy.ts
index d2717874e..8aa30e142 100644
--- a/cli/js/web/streams/queuing_strategy.ts
+++ b/cli/js/web/streams/queuing_strategy.ts
@@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import { setFunctionName } from "./internals.ts";
import { customInspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
export class CountQueuingStrategyImpl implements CountQueuingStrategy {
highWaterMark: number;
diff --git a/cli/js/web/streams/readable_byte_stream_controller.ts b/cli/js/web/streams/readable_byte_stream_controller.ts
index 65409dc1e..4a7ffae12 100644
--- a/cli/js/web/streams/readable_byte_stream_controller.ts
+++ b/cli/js/web/streams/readable_byte_stream_controller.ts
@@ -18,12 +18,12 @@ import {
readableStreamHasDefaultReader,
readableStreamGetNumReadRequests,
readableStreamCreateReadResult,
- setFunctionName,
} from "./internals.ts";
import type { ReadableStreamImpl } from "./readable_stream.ts";
import * as sym from "./symbols.ts";
import { assert } from "../../util.ts";
import { customInspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
export class ReadableByteStreamControllerImpl
implements ReadableByteStreamController {
diff --git a/cli/js/web/streams/readable_stream.ts b/cli/js/web/streams/readable_stream.ts
index 3191c0859..cf730d23a 100644
--- a/cli/js/web/streams/readable_stream.ts
+++ b/cli/js/web/streams/readable_stream.ts
@@ -9,7 +9,6 @@ import {
isWritableStream,
isWritableStreamLocked,
makeSizeAlgorithmFromSizeFunction,
- setFunctionName,
setPromiseIsHandledToTrue,
readableStreamCancel,
ReadableStreamGenericReader,
@@ -25,6 +24,7 @@ import type { ReadableStreamDefaultControllerImpl } from "./readable_stream_defa
import * as sym from "./symbols.ts";
import { customInspect } from "../console.ts";
import { AbortSignalImpl } from "../abort_signal.ts";
+import { setFunctionName } from "../util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class ReadableStreamImpl<R = any> implements ReadableStream<R> {
diff --git a/cli/js/web/streams/readable_stream_default_controller.ts b/cli/js/web/streams/readable_stream_default_controller.ts
index 47cb719c7..066bc8a8f 100644
--- a/cli/js/web/streams/readable_stream_default_controller.ts
+++ b/cli/js/web/streams/readable_stream_default_controller.ts
@@ -18,11 +18,11 @@ import {
readableStreamDefaultControllerGetDesiredSize,
resetQueue,
SizeAlgorithm,
- setFunctionName,
} from "./internals.ts";
import type { ReadableStreamImpl } from "./readable_stream.ts";
import * as sym from "./symbols.ts";
import { customInspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class ReadableStreamDefaultControllerImpl<R = any>
diff --git a/cli/js/web/streams/readable_stream_default_reader.ts b/cli/js/web/streams/readable_stream_default_reader.ts
index 01b679cd3..4ed0a5c7c 100644
--- a/cli/js/web/streams/readable_stream_default_reader.ts
+++ b/cli/js/web/streams/readable_stream_default_reader.ts
@@ -9,11 +9,11 @@ import {
readableStreamReaderGenericCancel,
readableStreamReaderGenericInitialize,
readableStreamReaderGenericRelease,
- setFunctionName,
} from "./internals.ts";
import type { ReadableStreamImpl } from "./readable_stream.ts";
import * as sym from "./symbols.ts";
import { customInspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class ReadableStreamDefaultReaderImpl<R = any>
diff --git a/cli/js/web/streams/transform_stream.ts b/cli/js/web/streams/transform_stream.ts
index 548a20b38..1c63a553b 100644
--- a/cli/js/web/streams/transform_stream.ts
+++ b/cli/js/web/streams/transform_stream.ts
@@ -7,7 +7,6 @@ import {
invokeOrNoop,
isTransformStream,
makeSizeAlgorithmFromSizeFunction,
- setFunctionName,
setUpTransformStreamDefaultControllerFromTransformer,
validateAndNormalizeHighWaterMark,
} from "./internals.ts";
@@ -16,6 +15,7 @@ import * as sym from "./symbols.ts";
import type { TransformStreamDefaultControllerImpl } from "./transform_stream_default_controller.ts";
import type { WritableStreamImpl } from "./writable_stream.ts";
import { customInspect, inspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class TransformStreamImpl<I = any, O = any>
diff --git a/cli/js/web/streams/transform_stream_default_controller.ts b/cli/js/web/streams/transform_stream_default_controller.ts
index 78beaf879..22087fb0b 100644
--- a/cli/js/web/streams/transform_stream_default_controller.ts
+++ b/cli/js/web/streams/transform_stream_default_controller.ts
@@ -4,7 +4,6 @@ import {
FlushAlgorithm,
isTransformStreamDefaultController,
readableStreamDefaultControllerGetDesiredSize,
- setFunctionName,
TransformAlgorithm,
transformStreamDefaultControllerEnqueue,
transformStreamDefaultControllerError,
@@ -14,6 +13,7 @@ import type { ReadableStreamDefaultControllerImpl } from "./readable_stream_defa
import * as sym from "./symbols.ts";
import type { TransformStreamImpl } from "./transform_stream.ts";
import { customInspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class TransformStreamDefaultControllerImpl<I = any, O = any>
diff --git a/cli/js/web/streams/writable_stream.ts b/cli/js/web/streams/writable_stream.ts
index 8a31f512d..2dea5311b 100644
--- a/cli/js/web/streams/writable_stream.ts
+++ b/cli/js/web/streams/writable_stream.ts
@@ -8,7 +8,6 @@ import {
isWritableStream,
isWritableStreamLocked,
makeSizeAlgorithmFromSizeFunction,
- setFunctionName,
setUpWritableStreamDefaultControllerFromUnderlyingSink,
writableStreamAbort,
writableStreamClose,
@@ -19,6 +18,7 @@ import * as sym from "./symbols.ts";
import type { WritableStreamDefaultControllerImpl } from "./writable_stream_default_controller.ts";
import type { WritableStreamDefaultWriterImpl } from "./writable_stream_default_writer.ts";
import { customInspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class WritableStreamImpl<W = any> implements WritableStream<W> {
diff --git a/cli/js/web/streams/writable_stream_default_controller.ts b/cli/js/web/streams/writable_stream_default_controller.ts
index b957c2c8f..0fe5f7ef9 100644
--- a/cli/js/web/streams/writable_stream_default_controller.ts
+++ b/cli/js/web/streams/writable_stream_default_controller.ts
@@ -6,7 +6,6 @@ import {
isWritableStreamDefaultController,
Pair,
resetQueue,
- setFunctionName,
SizeAlgorithm,
WriteAlgorithm,
writableStreamDefaultControllerClearAlgorithms,
@@ -15,6 +14,7 @@ import {
import * as sym from "./symbols.ts";
import type { WritableStreamImpl } from "./writable_stream.ts";
import { customInspect } from "../console.ts";
+import { setFunctionName } from "../util.ts";
export class WritableStreamDefaultControllerImpl<W>
implements WritableStreamDefaultController {
diff --git a/cli/js/web/streams/writable_stream_default_writer.ts b/cli/js/web/streams/writable_stream_default_writer.ts
index 09b47c69f..2e19af923 100644
--- a/cli/js/web/streams/writable_stream_default_writer.ts
+++ b/cli/js/web/streams/writable_stream_default_writer.ts
@@ -6,7 +6,6 @@ import {
isWritableStream,
isWritableStreamDefaultWriter,
isWritableStreamLocked,
- setFunctionName,
setPromiseIsHandledToTrue,
writableStreamCloseQueuedOrInFlight,
writableStreamDefaultWriterAbort,
@@ -19,6 +18,7 @@ import * as sym from "./symbols.ts";
import type { WritableStreamImpl } from "./writable_stream.ts";
import { customInspect } from "../console.ts";
import { assert } from "../../util.ts";
+import { setFunctionName } from "../util.ts";
export class WritableStreamDefaultWriterImpl<W>
implements WritableStreamDefaultWriter<W> {
diff --git a/cli/js/web/util.ts b/cli/js/web/util.ts
index 53ff8ef22..281048cd8 100644
--- a/cli/js/web/util.ts
+++ b/cli/js/web/util.ts
@@ -208,3 +208,11 @@ export function getHeaderValueParams(value: string): Map<string, string> {
export function hasHeaderValueOf(s: string, value: string): boolean {
return new RegExp(`^${value}[\t\s]*;?`).test(s);
}
+
+/** An internal function which provides a function name for some generated
+ * functions, so stack traces are a bit more readable.
+ *
+ * @internal */
+export function setFunctionName(fn: Function, value: string): void {
+ Object.defineProperty(fn, "name", { value, configurable: true });
+}