diff --git a/types/jasmine-reporters/jasmine-reporters-tests.ts b/types/jasmine-reporters/jasmine-reporters-tests.ts index 1fd792569f9d5b..3f0cb72f8f0b0c 100644 --- a/types/jasmine-reporters/jasmine-reporters-tests.ts +++ b/types/jasmine-reporters/jasmine-reporters-tests.ts @@ -48,7 +48,7 @@ function JUnitXmlReporterSpec_js() { filename: "text", failedExpectations: [], deprecationWarnings: [], - status: "text", + status: "passed", duration: null, properties: null, }; diff --git a/types/jasmine/index.d.ts b/types/jasmine/index.d.ts index 95eb737285d71b..7dd413f38c7aed 100644 --- a/types/jasmine/index.d.ts +++ b/types/jasmine/index.d.ts @@ -52,10 +52,20 @@ declare function xit(expectation: string, assertion?: jasmine.ImplementationCall /** * Mark a spec as pending, expectation results will be ignored. * If you call the function pending anywhere in the spec body, no matter the expectations, the spec will be marked pending. - * @param reason Reason the spec is pending. + * @param reason Reason why the spec is pending. */ declare function pending(reason?: string): void; +/** + * Mark a spec as not applicable. This is similar to {@link pending} except + * that the spec is never expected to pass in the current environment. + * + * If you call the function notApplicable anywhere in the spec body, no matter the expectations, the spec will be marked not applicable. + * @since 7.0.0 + * @param reason Reason why the spec is not applicable. + */ +declare function notApplicable(reason: string): void; + /** * Sets a user-defined property that will be provided to reporters as * part of the properties field of SpecResult. @@ -308,8 +318,9 @@ declare namespace jasmine { * Whether to forbid duplicate spec or suite names. If set to true, using * the same name multiple times in the same immediate parent suite is an * error. + * @deprecated Deprecated in jasmine 7. * @since 5.5.0 - * @default false + * @default true */ forbidDuplicateNames?: boolean | undefined; /** @@ -366,10 +377,6 @@ declare namespace jasmine { * @returns {Clock} */ function clock(): Clock; - /** - * @deprecated Private method that may be changed or removed in the future - */ - function DiffBuilder(): DiffBuilder; /** * Formats a value for display, taking into account the current set of @@ -723,16 +730,6 @@ declare namespace jasmine { message?: string | undefined; } - /** - * @deprecated Private type that may be changed or removed in the future - */ - interface DiffBuilder { - setRoots(actual: any, expected: any): void; - recordMismatch(formatter?: (actual: any, expected: any, path?: any, prettyPrinter?: any) => string): void; - withPath(pathComponent: string, block: () => void): void; - getMessage(): string; - } - interface MatchersUtil { equals(a: any, b: any): boolean; contains( @@ -792,14 +789,6 @@ declare namespace jasmine { topSuite(): Suite; } - interface HtmlReporter { - new(): any; - } - - interface HtmlSpecFilter { - new(): any; - } - interface Result { type: string; } @@ -1314,7 +1303,7 @@ declare namespace jasmine { /** * Once the spec has completed, this string represents the pass/fail status of this spec. */ - status: string; + status: "excluded" | "pending" | "notApplicable" | "failed" | "passed"; /** * The time in ms used by the spec execution, including any before/afterEach. @@ -1338,6 +1327,11 @@ declare namespace jasmine { */ pendingReason: string; + /** + * If the spec is not applicable, this will be the reason. + */ + notApplicableReason: string; + debugLogs: DebugLogEntry[] | null; /** @@ -1352,7 +1346,7 @@ declare namespace jasmine { } interface JasmineDoneInfo { - overallStatus: string; + overallStatus: "incomplete" | "failed" | "passed"; totalTime: number; incompleteReason: string; order: Order; @@ -1502,30 +1496,12 @@ declare namespace jasmine { extend(destination: any, source: any): any; } - interface JsApiReporter extends CustomReporter { - new(): any; - - started: boolean; - finished: boolean; - runDetails: JasmineDoneInfo; - - status(): string; - suiteResults(index: number, length: number): SuiteResult[]; - specResults(index: number, length: number): SpecResult[]; - suites(): { [id: string]: SuiteResult }; - specs(): SpecResult[]; - executionTime(): number; - } - interface Jasmine { Spec: Spec; clock: Clock; util: Util; } - var HtmlReporter: HtmlReporter; - var HtmlSpecFilter: HtmlSpecFilter; - /** * Default number of milliseconds Jasmine will wait for an asynchronous spec to complete. */ diff --git a/types/jasmine/jasmine-tests.ts b/types/jasmine/jasmine-tests.ts index c5a60bc4d7d91f..f3ca34a6f8c1de 100644 --- a/types/jasmine/jasmine-tests.ts +++ b/types/jasmine/jasmine-tests.ts @@ -447,6 +447,11 @@ describe("Pending specs", () => { pending(); // without reason pending("this is why it is pending"); }); + + it("can be declared by calling 'notApplicable' in the spec body", () => { + expect(true).toBe(false); + notApplicable("this is why it is not applicable"); + }); }); describe("setSpecProperty", () => { @@ -1300,33 +1305,6 @@ describe("jasmine.any", () => { }); }); -describe("DiffBuilder", () => { - it("records the actual and expected objects", () => { - const diffBuilder = jasmine.DiffBuilder(); - diffBuilder.setRoots({ x: "actual" }, { x: "expected" }); - diffBuilder.recordMismatch(); - - expect(diffBuilder.getMessage()).toEqual( - "Expected Object({ x: 'actual' }) to equal Object({ x: 'expected' }).", - ); - }); - - it("allows customization of the message", () => { - const diffBuilder = jasmine.DiffBuilder(); - diffBuilder.setRoots({ x: "bar" }, { x: "foo" }); - - function darthVaderFormatter(actual: any, expected: any, path: any) { - return `I find your lack of ${expected} disturbing. (was ${actual}, at ${path})`; - } - - diffBuilder.withPath("x", () => { - diffBuilder.recordMismatch(darthVaderFormatter); - }); - - expect(diffBuilder.getMessage()).toEqual("I find your lack of foo disturbing. (was bar, at $.x)"); - }); -}); - describe("custom asymmetry", () => { const tester: jasmine.AsymmetricMatcher = { asymmetricMatch: (actual: string, matchersUtil: jasmine.MatchersUtil) => { @@ -2537,70 +2515,6 @@ describe("Debug logging", function() { }); }); -(() => { - // from boot.js - const env = jasmine.getEnv(); - - const htmlReporter = new jasmine.HtmlReporter(); - env.addReporter(htmlReporter); - - const specFilter = new jasmine.HtmlSpecFilter(); - env.configure({ - specFilter: spec => { - return specFilter.matches(spec.getFullName()); - }, - }); - - env.setSpecProperty("name", "value"); - env.setSuiteProperty("other-name", null); - - const currentWindowOnload = window.onload; - window.onload = () => { - if (currentWindowOnload) { - (currentWindowOnload as any)(null); - } - htmlReporter.initialize(); - env.execute(); - }; - - afterAll(() => { - const jsApiReporter: jasmine.JsApiReporter = (window as any).jsApiReporter; - const suites = jsApiReporter.suites(); - const time = jsApiReporter.executionTime(); - - console.log("time", time); - - for (const k in suites) { - const suite: jasmine.SuiteResult = suites[k]; - console.log(suite); - console.log("id", suite.id); - console.log("description", suite.description); - console.log("fullName", suite.fullName); - console.log("filename", suite.filename); - console.log("fe", suite.failedExpectations); - - for (const fe of suite.failedExpectations) { - console.log(">> matcherName:", fe.matcherName); - console.log(">> passed:", fe.passed); - console.log(">> expected:", fe.expected); - console.log(">> actual:", fe.actual); - console.log(">> message:", fe.message); - console.log(">> stack:", fe.stack); - } - - console.log("dw", suite.deprecationWarnings); - - for (const fe of suite.deprecationWarnings) { - console.log(">> message:", fe.message); - } - - console.log("status", suite.status); - console.log("duraiton", suite.duration); - console.log("properties", suite.properties); - } - }); -})(); - jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; jasmine.MAX_PRETTY_PRINT_DEPTH = 40; diff --git a/types/jasmine/package.json b/types/jasmine/package.json index 4e98e712754ee1..1fdbb1a8457c4d 100644 --- a/types/jasmine/package.json +++ b/types/jasmine/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@types/jasmine", - "version": "6.0.9999", + "version": "7.0.9999", "projects": [ "http://jasmine.github.io" ], diff --git a/types/mysql/index.d.ts b/types/mysql/index.d.ts index 43d133ce33130c..2f35ac1ff84b22 100644 --- a/types/mysql/index.d.ts +++ b/types/mysql/index.d.ts @@ -625,7 +625,7 @@ export interface OkPacket { protocol41: boolean; } -export const enum Types { +export enum Types { DECIMAL = 0x00, // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html) TINY = 0x01, // aka TINYINT, 1 byte SHORT = 0x02, // aka SMALLINT, 2 bytes diff --git a/types/node-red__editor-client/index.d.ts b/types/node-red__editor-client/index.d.ts index 40234913ca8577..065189497ae1c4 100644 --- a/types/node-red__editor-client/index.d.ts +++ b/types/node-red__editor-client/index.d.ts @@ -1469,6 +1469,56 @@ declare namespace editorClient { * Widgets */ + interface WidgetAutoCompleteOptions { + /** + * If provided instead of `search`, this will look for any plugins + * registered with the given type that implement the `getCompletions` function. This + * can be an async function that returns an array of string completions. It does not support + * the full options object as above. + */ + completionPluginType?: string; + /** If `minLength` is 0, pressing down arrow will show the list */ + minLength?: number; + /** If provided, this will be passed to the `getCompletions` function of the plugin + * to allow the plugin to provide context-aware completions. + */ + node?: object; + /** + * A function that is called when the input value changes that should + * return a list of possible completions. If `done` is used, it must be called. + * @param value The current value of the + * @param done A callback function that will be called with the completions. + */ + search: + | ((value: string) => Array<{ value: string; label: string | JQuery }>) + | ((value: string, done: (result?: Array<{ value: string; label: string | JQuery }>) => void) => void); + } + + /** + * Attach to an to provide auto-complete + * @link https://nodered.org/docs/api/ui/autoComplete/ + */ + interface WidgetAutoComplete extends JQuery { + (options: WidgetAutoCompleteOptions): this; + /** + * Removes auto-complete functionality from the . + */ + (action: "destroy"): void; + } + + interface WidgetCheckboxSetOptions { + parent?: JQuery; + } + + interface WidgetCheckboxSet extends JQuery { + (options: WidgetCheckboxSetOptions): this; + (action: "addChild", child: JQuery): void; + (action: "disable"): void; + (action: "removeChild", child: JQuery): void; + (action: "state", state: boolean | null, supressEvent?: boolean, suppressParentUpdate?: boolean): void; + (action: "updateChild"): void; + } + interface WidgetEditableListOptions { /** * Determines whether a button is shown below the list that, when clicked, will add a new entry to the list. @@ -1486,10 +1536,28 @@ declare namespace editorClient { * @param data - the data object for the row */ addItem?: ((row: JQuery, index: number, data: T) => void) | undefined; + /** + * An array of button objects, that need to be added at the bottom of the editableList. + */ + buttons?: Array<{ + click: (this: JQuery, event: JQuery.ClickEvent) => void; + icon?: string; + id?: string; + label?: string; + title?: string; + }>; /** * If the list is sortable, this option allows items to be dragged from this list to any other jQuery sortable list, such as another editableList. */ connectWith?: JQuery.Selector | undefined; + /** + * A callback function that gets called to filter what items are visible in the list. + * + * @param data - the data object for the row + * + * The function should return true/false (boolean) to indicate whether the item should be visible. + */ + filter?: ((data: T) => boolean) | undefined; /** * Inserts the DOM/JQuery object as a header for the list. */ @@ -1501,13 +1569,17 @@ declare namespace editorClient { */ height?: number | "auto" | undefined; /** - * A callback function that gets called to filter what items are visible in the list. - * - * @param data - the data object for the row + * If set to true, each row is displayed with a delete button on the right-hand side. + * Clicking the button will remove the row from the list and trigger the removeItem callback, if set. + */ + removable?: boolean | undefined; + /** + * A function that is called when an item is removed from the list. * - * The function should return true/false (boolean) to indicate whether the item should be visible. + * @param data - the original data item for the item + * The remove can be triggered by either clicking an item’s remove button, or calling the remoteItem method. */ - filter?: ((data: T) => boolean) | undefined; + removeItem?: ((data: T) => void) | undefined; /** * A function that gets called when the size of the list changes. */ @@ -1554,20 +1626,9 @@ declare namespace editorClient { * Each row element stores the original data for the item under property called data. */ sortItems?: ((items: JQuery[]) => void) | undefined; - /** - * If set to true, each row is displayed with a delete button on the right-hand side. - * Clicking the button will remove the row from the list and trigger the removeItem callback, if set. - */ - removable?: boolean | undefined; - /** - * A function that is called when an item is removed from the list. - * - * @param data - the original data item for the item - * The remove can be triggered by either clicking an item’s remove button, or calling the remoteItem method. - */ - removeItem?: ((data: T) => void) | undefined; } + /** @link https://nodered.org/docs/api/ui/editableList/ */ interface WidgetEditableList extends JQuery { /** * Inits EditableList @@ -1575,76 +1636,349 @@ declare namespace editorClient { * * More info: https://nodered.org/docs/api/ui/editableList/ */ - (opts: WidgetEditableListOptions): this; // eslint-disable-line @definitelytyped/no-unnecessary-generics + (options: WidgetEditableListOptions): this; // eslint-disable-line @definitelytyped/no-unnecessary-generics /** * Adds an item to the end of the list. * - * @param value - An object that will be associated with the item in the list. + * @param value An object that will be associated with the item in the list. */ (action: "addItem", value: object): void; /** * Adds items contained in an array to the end of the list. - * @param value - An array of objects that will be associated with the item in the list. + * @param value An array of objects that will be associated with the item in the list. */ (action: "addItems", value: object[]): void; /** - * Removes an item from the list. - * @param value - The object that identifies the item to be removed. + * Cancels the items move/reorder. */ - (action: "removeItem", value: object): void; // tslint:disable-line:unified-signatures + (action: "cancel"): void; /** - * Sets the width of the editableList. This must be used in place of the standard jQuery.width() function as it ensures the component resizes properly. + * Clears the list of all items. This does not trigger any callbacks. */ - (action: "width", value: string | number): void; + (action: "empty"): void; /** - * Sets the height of the editableList. This must be used in place of the standard jQuery.height() function as it ensures the component resizes properly. + * Filters the list to show/hide items based on the active filter function and + * returns the number of visible items. + * If filter is not provided, the list is filtered using the current active filter function. + * If filter is null, the filter is removed. */ - (action: "height", value: string | number): void; // tslint:disable-line:unified-signatures + (action: "filter", filter?: (data: object) => boolean): number; /** - * Gets an Array of all list items. Each item is the jQuery DOM element for the item. - * Each element stores the original data for the item under property called data. + * Gets the item data associated with the given item. Returns null if not found. */ - (action: "items"): JQuery; + (action: "getItem", item: JQuery): object | null; /** - * Clears the list of all items. This does not trigger any callbacks. + * Gets item at index. Returns item data or undefined. + * @param value Item index: 0..length-1 */ - (action: "empty"): void; + (action: "getItemAt", value: number): object | undefined; /** - * Filters the list to show/hide items based on the active filter function and returns the number of visible items. - * If filter is not provided, the list is filtered using the current active filter function. - * If filter is null, the filter is removed. + * Sets the height of the editableList. This must be used in place of the standard jQuery.height() + * function as it ensures the component resizes properly. */ - (action: "filter", value?: (data: object) => boolean): number; + (action: "height", value: string | number): void; /** - * Scrolls the list to ensure the specific item is in view. - * @param value - An object associated with the item in the list. + * Inserts an item at the specified index. */ - (action: "show", value: object): void; // tslint:disable-line:unified-signatures + (action: "insertItemAt", value: object, index: number): void; /** - * Get item at index. Returns item dat or undefined. - * @param value - Item index: 0..length-1 + * Gets an Array of all list items. Each item is the jQuery DOM element for the item. + * Each element stores the original data for the item under property called data. */ - (action: "getItemAt", value: number): object | undefined; + (action: "items"): JQuery[]; /** - * Get index of item. Returns index or -1 if not found - * @param value - Item data + * Gets index of item. Returns index or -1 if not found. + * @param value Item data */ (action: "indexOf", value: object): number; + /** + * Gets the number of list items. + */ + (action: "length"): number; + /** + * Removes an item from the list. + * @param value The object that identifies the item to be removed. + * @param detach Remove or detach the item + */ + (action: "removeItem", value: object, detach?: boolean): void; + /** + * Scrolls the list to ensure the specific item is shown. + * @param value An item into the list. + */ + (action: "show", value: object): void; /** * Sorts the list using the active sort function. - * - * @param value - A callback function that gets called to compare two items in the list to determine their order. - * + * @param value A callback function that gets called to compare two items in the list to determine their order. * If the function returns a value less than 0, itemDataA comes before itemDataB. * If the function returns 0, the items are left unchanged. * If the function returns a value greater than 0, itemDataA comes after itemDataB. */ (action: "sort", value: (itemDataA: object, itemDataB: object) => number): void; + /** - * Gets the number of list items. + * Sets the width of the editableList. This must be used in place of the standard jQuery.width() + * function as it ensures the component resizes properly. */ - (action: "length"): number; + (action: "width", value: string | number): void; + } + + interface WidgetSearchBoxOptions { + /** + * Delay, in ms, after a keystroke before firing change event + */ + delay: number; + /** + * The minimum length of text before firing a change event + */ + minimumLength: number; + } + + /** @link https://nodered.org/docs/api/ui/searchBox/ */ + interface WidgetSearchBox extends JQuery { + (options: WidgetSearchBoxOptions): this; + /** + * Triggers a change event on the search input. + */ + (action: "change"): void; + /** + * Sets or clears a sub-label on the input. This can be used to provide + * a feedback on the number of matches, or number of available entries to search. + * The standard pattern to follow is: + * - if the search box is empty, set it to the number of available items: "300" + * - if the search box is not empty, set it to the number of matching items, + * as well as the number of available items: "120 / 300" + * If value is `null`, `undefined` or `blank`, the count field is hidden. + */ + (action: "count", value?: null | string): void; + /** + * Gets the current value of the search input. + */ + (action: "value"): string; + /** + * Sets the current value of the search input. + */ + (action: "value", value: string): void; } + interface WidgetToggleButtonOptions { + /** + * The base css class to apply, default "red-ui-button" (alternative eg "red-ui-sidebar-header-button") + */ + baseClass?: string; + /** + * Additional classes to apply to the button - eg "red-ui-button-small" + */ + class?: string; + /** + * The icon for "enabled" state, default "fa-check-square-o" + */ + enabledIcon?: string; + /** + * The label for "enabled" state, default "Enabled" ("editor:workspace.enabled") + */ + enabledLabel?: string; + /** + * The icon for "disabled" state, default "fa-square-o" + */ + disabledIcon?: string; + /** + * The label for "disabled" state, default "Disabled" ("editor:workspace.disabled") + */ + disabledLabel?: string; + /** + * If true, the button will show "enabled" when the checkbox is not selected and vice versa. + */ + invertState?: boolean; + } + + interface WidgetToogleButton extends JQuery { + (options: WidgetToggleButtonOptions): this; + } + + /** @link https://nodered.org/docs/api/ui/treeList/#options-data */ + interface WidgetTreeListData { + /** + * Whether to display a checkbox for the item. + */ + checkbox?: boolean; + /** + * Prevent a parent item from being collapsed. Default true. + */ + collapsible?: boolean; + /** + * An array of child items, or a function that calls the `done` callback with an array of child items. + */ + children?: + | WidgetTreeListData[] + | ((done: (children: WidgetTreeListData[]) => void, item: WidgetTreeListData) => void); + /** + * Don't build any UI elements for the item's children until it is expanded by the user. + */ + deferBuild?: boolean; + /** + * Custom DOM element to use for the item. Ignored if `label` is set. + */ + element?: HTMLElement | JQuery; + /** + * Whether to show the child items by default. + */ + expanded?: boolean; + /** + * Icon for the item. + */ + icon?: string; + /** + * Label for the item. + */ + label?: string; + /** + * Radio group name. If present, display radio box using group-name to set radio group. + */ + radio?: string; + /** + * Whether the item is selected or not. + */ + selected?: boolean; + /** + * A sub-label for the item. + */ + sublabel?: string; + } + + interface WidgetTreeListItem extends WidgetTreeListData { + /** + * The parent item in the tree, or undefined if this is a root item. + */ + parent?: WidgetTreeListItem; + /** + * The depth of the item in the tree (0 == root). + */ + depth: number; + /** + * TreeList-specific properties and methods. + */ + treeList: { + /** + * The container element for this item. + */ + container: HTMLElement | JQuery; + /** + * The label element for this item. + */ + label: HTMLElement | JQuery; + /** + * The editableList instance this item is in. + */ + parentList: JQuery; + /** + * Removes the item from the tree. + * @param detach If true, detaches the element to preserve event handlers. + */ + remove(detach?: boolean): void; + /** + * Turns an element with children into a leaf node, removing UI decoration. + * @param detachChildElements If true, detaches children with custom elements to preserve event handlers. + */ + makeLeaf(detachChildElements?: boolean): void; + /** + * Turns an element into a parent node, adding UI decoration. + * @param children Optional children to add as child nodes. + */ + makeParent(children?: WidgetTreeListItem[]): void; + /** + * Adds a child item at the specified position. + * @param newItem The new child item to insert. + * @param position The position to insert at. + * @param select If true, selects the item after adding. + */ + insertChildAt(newItem: WidgetTreeListItem, position: number, select?: boolean): void; + /** + * Appends a child item. + * @param newItem The new child item to add. + * @param select If true, selects the item after adding. + */ + addChild(newItem: WidgetTreeListItem, select?: boolean): void; + /** + * Expands the parent item to show children. + * @param done Optional callback when expansion is complete. + */ + expand(done?: () => void): void; + /** + * Collapses the parent item to hide children. + */ + collapse(): void; + /** + * Sorts the children using the provided sort function. + * @param sortFunction The function to sort children. + */ + sortChildren(sortFunction: (a: WidgetTreeListItem, b: WidgetTreeListItem) => number): void; + /** + * Replaces the custom element for the item. + * @param element The new element to use. + */ + replaceElement(element: HTMLElement | JQuery): void; + }; + } + + /** @link https://nodered.org/docs/api/ui/treeList/#options */ + interface WidgetTreeListOptions { + /** + * Automatically select items when navigating with keyboard. + * Default true. If the list has checkboxed items, you probably want to set this to false. + */ + autoSelect?: boolean; + /** + * Initial items to display in tree + */ + data: WidgetTreeListData[]; + /** + * If true, .selected will return an array of results; otherwise, returns the first selected item. + */ + multi?: boolean; + /** + * Whether individual items can be selected. Default true. + */ + selectable?: boolean; + /** + * If 'sortable' is set, then setting this to false prevents items being sorted to the top level of the tree. + */ + rootSortable?: boolean; + /** + * Enable sorting. Boolean or string. (TODO: see editableList) + */ + sortable?: boolean | string; + } + + /** @link https://nodered.org/docs/api/ui/treeList/ */ + interface WidgetTreeList extends JQuery { + (options: WidgetTreeListOptions): this; + (action: "clearSelection"): void; + /** + * Returns the data the treeList is displaying. + * If any items had the `selected` property set on them, its value will reflect the current checkbox state. + */ + (action: "data"): WidgetTreeListData[]; + /** + * Sets the data to be displayed by the list. + */ + (action: "data", items: WidgetTreeListData[]): void; + /** + * Removes all items from the list. + */ + (action: "empty"): void; + (action: "filter", filter: (item: WidgetTreeListItem) => boolean): number; + (action: "get", id: string): WidgetTreeListItem | null; + (action: "reveal", item: string | WidgetTreeListItem): void; + ( + action: "select", + item: WidgetTreeListItem | WidgetTreeListItem[], + triggerEvent?: boolean, + deselectExisting?: boolean, + ): void; + (action: "selected"): WidgetTreeListItem | WidgetTreeListItem[] | undefined; + (action: "show", item: string | WidgetTreeListItem, done?: () => void): void; + } + + /** @link https://nodered.org/docs/api/ui/typedInput/#options */ interface WidgetTypedInputOptions { /** If defined, sets the default type of the input if typeField is not set. */ default?: WidgetTypedInputType | string | undefined; @@ -1658,6 +1992,7 @@ declare namespace editorClient { typeField?: JQuery.Selector | JQuery | undefined; } + /** @link https://nodered.org/docs/api/ui/typedInput/#types */ type WidgetTypedInputType = | "msg" | "flow" @@ -1670,23 +2005,50 @@ declare namespace editorClient { | "re" | "date" | "jsonata" - | "env"; + | "env" + | "node" + | "cred" + | "conf-types"; + /** @link https://nodered.org/docs/api/ui/typedInput/#types-typedefinition */ interface WidgetTypedInputTypeDefinition { - /** The identifier for the type */ - value: string; - /** A label to display in the type menu */ - label?: string | undefined; + /** + * If set, enable autoComplete on the input, using this function to get completion suggestions. + * This option cannot be used with {@link options}, {@link hasValue}=false or {@link valueLabel}. + */ + autoComplete?: + | ((value: string) => Array<{ value: string; label: string | JQuery }>) + | ((value: string, done: (result?: Array<{ value: string; label: string | JQuery }>) => void) => void); + /** A callback function that gets called when the input needs to be expanded */ + expand?: (this: WidgetTypedInput) => void; + /** Set to false if there is no value associated with the type. */ + hasValue?: boolean | undefined; /** An icon to display in the type menu */ icon?: string | undefined; + /** The type of input. e.g. password,email... */ + inputType?: string | undefined; + /** A label to display in the type menu */ + label?: string | undefined; + /** If {@link options} is set, this can enable multiple selection of them. */ + multiple?: boolean; /** If the type has a fixed set of values, this is an array of string options for the value. For example, ["true","false"] for the boolean type. */ options?: string[] | Array<{ value: string; label: string }> | undefined; - /** Set to false if there is no value associated with the type. */ - hasValue?: boolean | undefined; /** A function to validate the value for the type. */ - validate?: ((v: string) => boolean) | RegExp | undefined; + validate?: + | ((value: string) => boolean) + | ((value: string, options: {}) => string | boolean) + | RegExp; + /** The identifier for the type */ + value: string; + /** + * A function that generates the label for a given value. + * @param container the DOM element the label should be constructed in + * @param value The value of the type + */ + valueLabel?: (container: JQuery, value: string) => void; } + /** @link https://nodered.org/docs/api/ui/typedInput/ */ interface WidgetTypedInput extends JQuery { /** * Inits TypedInput @@ -1694,26 +2056,50 @@ declare namespace editorClient { * chosen, including options for string, number and boolean types. * More info: https://nodered.org/docs/api/ui/typedInput/ */ - (opts: WidgetTypedInputOptions): this; + (options: WidgetTypedInputOptions): this; + /** + * Disables the typedInput. + */ + (action: "disable", value?: boolean): void; + /** + * Gets the disabled state of the typedInput. + */ + (action: "disabled"): boolean; + /** + * Enables the typedInput. + */ + (action: "enable"): void; + /** + * Focuses the typedInput. + */ + (action: "focus"): void; + /** + * Hides the typedInput. + */ (action: "hide"): void; - (action: "show"): void; // tslint:disable-line:unified-signatures + /** + * Shows the typedInput. + */ + (action: "show"): void; /** * Gets the selected type of the typedInput. */ - (action: "type"): WidgetTypedInputType | string; + (action: "type"): T; // eslint-disable-line @definitelytyped/no-unnecessary-generics /** * Sets the selected type of the typedInput. */ - (action: "type", value: WidgetTypedInputType | string): void; + (action: "type", value: T): void; // eslint-disable-line @definitelytyped/no-unnecessary-generics /** * Sets the list of types offered by the typedInput. */ (action: "types", value: Array): void; /** - * Triggers a revalidation of the typedInput’s type/value. This occurs automatically - * whenever the type or value change, but this method allows it to be run manually. + * Triggers manually a revalidation of the typedInput’s type/value. + * This occurs automatically whenever the type or value change. */ (action: "validate"): boolean; + /** @since v4.0.0 */ + (action: "validate", options: { returnErrorMessage: boolean }): string | boolean; /** * Gets the value of the typedInput. */ @@ -1732,7 +2118,12 @@ declare namespace editorClient { declare global { interface JQuery { + autoComplete: editorClient.WidgetAutoComplete; + checkboxSet: editorClient.WidgetCheckboxSet; editableList: editorClient.WidgetEditableList; + searchBox: editorClient.WidgetSearchBox; + toggleButton: editorClient.WidgetToogleButton; + treeList: editorClient.WidgetTreeList; typedInput: editorClient.WidgetTypedInput; } } diff --git a/types/node-red__editor-client/node-red__editor-client-tests.ts b/types/node-red__editor-client/node-red__editor-client-tests.ts index 5202d564925e7c..ee9bc8528a72f7 100644 --- a/types/node-red__editor-client/node-red__editor-client-tests.ts +++ b/types/node-red__editor-client/node-red__editor-client-tests.ts @@ -258,6 +258,106 @@ function redTests(RED: editorClient.RED) { RED.actions.invoke("core:generate-node-names", myNodeDef, { generateHistory: false }); } +function widgetAutoCompleteTest() { + type MyAutoCompleteOptions = editorClient.WidgetAutoCompleteOptions; + + const myAutoCompleteOptions: MyAutoCompleteOptions = { + minLength: 0, + search: (value: string) => { + // $ExpectType string + value; + return []; + }, + // @ts-expect-error + wrongProperty: true, + }; + + const mySecondAutoCompleteOptions: MyAutoCompleteOptions = { + search: (value, done) => { + // $ExpectType string + value; + // $ExpectType (result?: { value: string; label: string | JQuery; }[] | undefined) => void + done; + }, + // @ts-expect-error + node: "", + }; + + const myAutoComplete: editorClient.WidgetAutoComplete = $("input").autoComplete({ + search: (_value: string) => { + return []; + }, + }); +} + +function widgetCheckboxSetTest() { + type MyCheckboxSetOptions = editorClient.WidgetCheckboxSetOptions; + + const myCheckboxSetOptions: MyCheckboxSetOptions = { + // $ExpectType JQuery + parent: $("div"), + }; + + const wrongOptions: MyCheckboxSetOptions = { + // @ts-expect-error + parent: "wrong", + }; + + const wrongProperty: MyCheckboxSetOptions = { + // @ts-expect-error + node: "", + }; + + const widget: editorClient.WidgetCheckboxSet = $("input").checkboxSet({ + parent: $("div"), + }); + + const child: JQuery = $("div"); + + widget("addChild", child); + widget("removeChild", child); + + widget("disable"); + widget("updateChild"); + + widget("state", true); + widget("state", false); + widget("state", null); + + widget("state", true, true); + widget("state", true, false, true); + + // @ts-expect-error + widget("addChild"); + + // @ts-expect-error + widget("addChild", "wrong"); + + // @ts-expect-error + widget("removeChild", "wrong"); + + // @ts-expect-error + widget("disable", true); + + // @ts-expect-error + widget("updateChild", true); + + // @ts-expect-error + widget("state"); + + // @ts-expect-error + widget("state", "wrong"); + + // @ts-expect-error + widget("state", true, "wrong"); + + // @ts-expect-error + widget("state", true, false, "wrong"); + + // @ts-expect-error + widget("wrongAction"); +} + function widgetEditableListTests() { interface MyItemData { key: string; @@ -320,6 +420,333 @@ function widgetEditableListTests() { }; } +function widgetSearchBoxTest() { + type MySearchBoxOptions = editorClient.WidgetSearchBoxOptions; + + const mySearchBoxOptions: MySearchBoxOptions = { + delay: 100, + minimumLength: 2, + }; + + const mySecondSearchBoxOptions: MySearchBoxOptions = { + delay: 0, + minimumLength: 0, + // @ts-expect-error + wrongProperty: true, + }; + + const myWrongSearchBoxOptions: MySearchBoxOptions = { + // @ts-expect-error + delay: "100", + minimumLength: 2, + }; + + // @ts-expect-error + const mySecondWrongSearchBoxOptions: MySearchBoxOptions = { + delay: 100, + }; + + type MySearchBox = editorClient.WidgetSearchBox; + + const mySearchBox: MySearchBox = $("input").searchBox({ + delay: 100, + minimumLength: 2, + }); + + mySearchBox("change"); + mySearchBox("count"); + mySearchBox("count", null); + mySearchBox("count", "120 / 300"); + mySearchBox("value"); + mySearchBox("value", "test"); + + // @ts-expect-error + mySearchBox("wrongAction"); + + // @ts-expect-error + mySearchBox("change", true); + + // @ts-expect-error + mySearchBox("count", 100); + + // @ts-expect-error + mySearchBox("value", 100); +} + +function widgetToggleButtonTest() { + type MyToggleButtonOptions = editorClient.WidgetToggleButtonOptions; + + const myToggleButtonOptions: MyToggleButtonOptions = { + baseClass: "red-ui-button", + class: "red-ui-button-small", + enabledIcon: "fa-check-square-o", + enabledLabel: "Enabled", + disabledIcon: "fa-square-o", + disabledLabel: "Disabled", + invertState: false, + }; + + const mySecondToggleButtonOptions: MyToggleButtonOptions = { + baseClass: "custom-button", + enabledLabel: "On", + disabledLabel: "Off", + invertState: true, + // @ts-expect-error + wrongProperty: true, + }; + + const myWrongToggleButtonOptions: MyToggleButtonOptions = { + // @ts-expect-error + invertState: "true", + }; + + const mySecondWrongToggleButtonOptions: MyToggleButtonOptions = { + // @ts-expect-error + enabledLabel: 123, + }; + + const myToggleButton: editorClient.WidgetToogleButton = $("input").toggleButton({}); +} + +function widgetTreeListDataTest() { + type MyTreeListData = editorClient.WidgetTreeListData; + type MyTreeListOptions = editorClient.WidgetTreeListOptions; + + const myTreeListData: MyTreeListData = { + checkbox: true, + collapsible: false, + children: [ + { + label: "Child", + selected: true, + }, + ], + deferBuild: true, + element: $("div")[0], + expanded: true, + icon: "fa-folder", + label: "Parent", + radio: "group", + selected: false, + sublabel: "Sub-label", + }; + + const mySecondTreeListData: MyTreeListData = { + label: "Lazy parent", + children: (done, item) => { + // $ExpectType (children: WidgetTreeListData[]) => void + done; + // $ExpectType WidgetTreeListData + item; + + done([]); + }, + }; + + const myTreeListOptions: MyTreeListOptions = { + autoSelect: false, + data: [myTreeListData], + multi: true, + selectable: true, + rootSortable: false, + sortable: "sortable", + }; + + const mySecondTreeListOptions: MyTreeListOptions = { + data: [], + sortable: true, + // @ts-expect-error + wrongProperty: true, + }; + + const myWrongTreeListData: MyTreeListData = { + // @ts-expect-error + checkbox: "true", + }; + + const mySecondWrongTreeListData: MyTreeListData = { + // @ts-expect-error + children: "wrong", + }; + + const myThirdWrongTreeListData: MyTreeListData = { + // @ts-expect-error + element: "wrong", + }; + + const myWrongTreeListOptions: MyTreeListOptions = { + // @ts-expect-error + data: {}, + }; + + const mySecondWrongTreeListOptions: MyTreeListOptions = { + // @ts-expect-error + sortable: 123, + }; +} + +function widgetTreeListItemTest() { + type MyTreeListItem = editorClient.WidgetTreeListItem; + + const myTreeListItem: MyTreeListItem = { + label: "Item", + depth: 0, + treeList: { + container: $("div"), + label: $("label"), + parentList: $("div"), + remove: (detach) => { + // $ExpectType boolean | undefined + detach; + }, + makeLeaf: (detachChildElements) => { + // $ExpectType boolean | undefined + detachChildElements; + }, + makeParent: (children) => { + // $ExpectType WidgetTreeListItem[] | undefined + children; + }, + insertChildAt: (newItem, position, select) => { + // $ExpectType WidgetTreeListItem + newItem; + // $ExpectType number + position; + // $ExpectType boolean | undefined + select; + }, + addChild: (newItem, select) => { + // $ExpectType WidgetTreeListItem + newItem; + // $ExpectType boolean | undefined + select; + }, + expand: (done) => { + // $ExpectType (() => void) | undefined + done; + }, + collapse: () => {}, + sortChildren: (sortFunction) => { + // $ExpectType (a: WidgetTreeListItem, b: WidgetTreeListItem) => number + sortFunction; + }, + replaceElement: (element) => { + // $ExpectType HTMLElement | JQuery + element; + }, + }, + }; +} + +function widgetTreeListActionsTest() { + type MyTreeList = editorClient.WidgetTreeList; + type MyTreeListData = editorClient.WidgetTreeListData; + type MyTreeListItem = editorClient.WidgetTreeListItem; + + const myTreeList: MyTreeList = $("div").treeList({ data: [] }); + + const item: MyTreeListItem = { + label: "Item", + depth: 0, + treeList: { + container: $("div"), + label: $("label"), + parentList: $("div"), + remove: () => {}, + makeLeaf: () => {}, + makeParent: () => {}, + insertChildAt: () => {}, + addChild: () => {}, + expand: () => {}, + collapse: () => {}, + sortChildren: () => {}, + replaceElement: () => {}, + }, + }; + + const items: MyTreeListItem[] = [item]; + const data: MyTreeListData[] = []; + + myTreeList({ + data, + }); + + myTreeList("clearSelection"); + + myTreeList("data"); + myTreeList("data", data); + + myTreeList("empty"); + + const filterResult = myTreeList("filter", (filterItem) => { + // $ExpectType WidgetTreeListItem + filterItem; + + return filterItem.selected === true; + }); + + // $ExpectType number + filterResult; + + const getResult = myTreeList("get", "item-id"); + + // $ExpectType WidgetTreeListItem | null + getResult; + + myTreeList("reveal", "item-id"); + myTreeList("reveal", item); + + myTreeList("select", item); + myTreeList("select", items); + myTreeList("select", item, true); + myTreeList("select", item, false, true); + + const selected = myTreeList("selected"); + + // $ExpectType WidgetTreeListItem | WidgetTreeListItem[] | undefined + selected; + + myTreeList("show", "item-id"); + myTreeList("show", item); + myTreeList("show", item, () => {}); + + // @ts-expect-error + myTreeList("wrongAction"); + + // @ts-expect-error + myTreeList("data", "wrong"); + + // @ts-expect-error + myTreeList("filter", "wrong"); + + // @ts-expect-error + myTreeList("get", 123); + + // @ts-expect-error + myTreeList("reveal", 123); + + // @ts-expect-error + myTreeList("select", "wrong"); + + // @ts-expect-error + myTreeList("select", item, "wrong"); + + // @ts-expect-error + myTreeList("select", item, false, "wrong"); + + // @ts-expect-error + myTreeList("show", 123); + + // @ts-expect-error + myTreeList("show", item, "wrong"); + + // @ts-expect-error + myTreeList("empty", true); + + // @ts-expect-error + myTreeList("clearSelection", true); +} + function widgetTypedInputTests() { const goodType: editorClient.WidgetTypedInputType = "msg"; // @ts-expect-error diff --git a/types/protractor-beautiful-reporter/protractor-beautiful-reporter-tests.ts b/types/protractor-beautiful-reporter/protractor-beautiful-reporter-tests.ts index 7c6bfff2ad586b..e476fc20ddc2cc 100644 --- a/types/protractor-beautiful-reporter/protractor-beautiful-reporter-tests.ts +++ b/types/protractor-beautiful-reporter/protractor-beautiful-reporter-tests.ts @@ -289,6 +289,7 @@ function app_reporter_js() { const result: jasmine.SpecResult = { passedExpectations: [], pendingReason: "text", + notApplicableReason: "", debugLogs: [], id: "text", filename: "text", @@ -296,7 +297,7 @@ function app_reporter_js() { fullName: "text", failedExpectations: [], deprecationWarnings: [], - status: "text", + status: "passed", duration: 0, properties: {}, }; diff --git a/types/react-reconciler/index.d.ts b/types/react-reconciler/index.d.ts index c0762387a68005..20cf4f1c01097f 100644 --- a/types/react-reconciler/index.d.ts +++ b/types/react-reconciler/index.d.ts @@ -7,6 +7,7 @@ declare function ReactReconciler< Container, Instance, TextInstance, + ActivityInstance, SuspenseInstance, HydratableInstance, FormInstance, @@ -16,6 +17,11 @@ declare function ReactReconciler< TimeoutHandle, NoTimeout, TransitionStatus, + SuspendedState, + RendererInspectionConfig, + FormStateMarkerInstance, + HoistableRoot, + Resource, >( /* eslint-enable @definitelytyped/no-unnecessary-generics */ config: ReactReconciler.HostConfig< @@ -24,6 +30,7 @@ declare function ReactReconciler< Container, Instance, TextInstance, + ActivityInstance, SuspenseInstance, HydratableInstance, FormInstance, @@ -32,7 +39,12 @@ declare function ReactReconciler< ChildSet, TimeoutHandle, NoTimeout, - TransitionStatus + TransitionStatus, + SuspendedState, + RendererInspectionConfig, + FormStateMarkerInstance, + HoistableRoot, + Resource >, ): ReactReconciler.Reconciler; @@ -43,6 +55,7 @@ declare namespace ReactReconciler { Container, Instance, TextInstance, + ActivityInstance, SuspenseInstance, HydratableInstance, FormInstance, @@ -52,6 +65,11 @@ declare namespace ReactReconciler { TimeoutHandle, NoTimeout, TransitionStatus, + SuspendedState, + RendererInspectionConfig, + FormStateMarkerInstance, + HoistableRoot, + Resource, > { // ------------------- // Modes @@ -94,6 +112,30 @@ declare namespace ReactReconciler { */ supportsPersistence: boolean; + // ------------------- + // Renderer metadata + // ------------------- + + /** + * The version of your renderer. React DevTools reports this alongside the reconciler version, which may differ for third-party renderers. + */ + rendererVersion: string; + + /** + * The npm package name of your renderer, reported to React DevTools. + */ + rendererPackageName: string; + + /** + * Extra renderer-specific configuration exposed to React DevTools as `rendererConfig`. Return `null` if you have nothing to expose. + */ + extraDevToolsConfig: RendererInspectionConfig | null; + + /** + * Binds a `console` method call (as captured by React's replaying of Server console logs on the client) so it can be invoked later, optionally tagging it with an environment name badge. + */ + bindToConsole(methodName: string, args: any[], badgeName: string): () => any; + // ------------------- // Core Methods // ------------------- @@ -180,7 +222,7 @@ declare namespace ReactReconciler { * * This method happens **in the render phase**. Do not mutate the tree from it. */ - getChildHostContext(parentHostContext: HostContext, type: Type, rootContainer: Container): HostContext; + getChildHostContext(parentHostContext: HostContext, type: Type): HostContext; /** * Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But in some cases it might make sense to only expose some part of it. @@ -404,11 +446,25 @@ declare namespace ReactReconciler { // ------------------- supportsHydration: boolean; - canHydrateInstance?(instance: HydratableInstance, type: Type, props: Props): null | Instance; + canHydrateInstance?( + instance: HydratableInstance, + type: Type, + props: Props, + inRootOrSingleton: boolean, + ): null | Instance; + + canHydrateTextInstance?( + instance: HydratableInstance, + text: string, + inRootOrSingleton: boolean, + ): null | TextInstance; - canHydrateTextInstance?(instance: HydratableInstance, text: string): null | TextInstance; + canHydrateActivityInstance?( + instance: HydratableInstance, + inRootOrSingleton: boolean, + ): null | ActivityInstance; - canHydrateSuspenseInstance?(instance: HydratableInstance): null | SuspenseInstance; + canHydrateSuspenseInstance?(instance: HydratableInstance, inRootOrSingleton: boolean): null | SuspenseInstance; isSuspenseInstancePending?(instance: SuspenseInstance): boolean; @@ -424,73 +480,111 @@ declare namespace ReactReconciler { instance: Instance, type: Type, props: Props, - rootContainerInstance: Container, hostContext: HostContext, internalInstanceHandle: any, - ): null | any[]; + ): boolean; - hydrateTextInstance?(textInstance: TextInstance, text: string, internalInstanceHandle: any): boolean; + hydrateTextInstance?( + textInstance: TextInstance, + text: string, + internalInstanceHandle: any, + parentProps: null | Props, + ): boolean; + + hydrateActivityInstance?(activityInstance: ActivityInstance, internalInstanceHandle: any): void; hydrateSuspenseInstance?(suspenseInstance: SuspenseInstance, internalInstanceHandle: any): void; - getNextHydratableInstanceAfterSuspenseInstance?(suspenseInstance: SuspenseInstance): null | HydratableInstance; + getNextHydratableInstanceAfterActivityInstance?(activityInstance: ActivityInstance): null | HydratableInstance; - // Returns the SuspenseInstance if this node is a direct child of a - // SuspenseInstance. I.e. if its previous sibling is a Comment with - // SUSPENSE_x_START_DATA. Otherwise, null. - getParentSuspenseInstance?(targetInstance: any): null | SuspenseInstance; + getNextHydratableInstanceAfterSuspenseInstance?(suspenseInstance: SuspenseInstance): null | HydratableInstance; commitHydratedContainer?(container: Container): void; - commitHydratedSuspenseInstance?(suspenseInstance: SuspenseInstance): void; + commitHydratedInstance?(instance: Instance, type: Type, props: Props, internalHandle: OpaqueHandle): void; - didNotMatchHydratedContainerTextInstance?( - parentContainer: Container, - textInstance: TextInstance, - text: string, - ): void; + commitHydratedActivityInstance?(activityInstance: ActivityInstance): void; - didNotMatchHydratedTextInstance?( - parentType: Type, - parentProps: Props, - parentInstance: Instance, - textInstance: TextInstance, - text: string, - ): void; + finalizeHydratedChildren?( + instance: Instance, + type: Type, + props: Props, + hostContext: HostContext, + ): boolean; - didNotHydrateContainerInstance?(parentContainer: Container, instance: HydratableInstance): void; + flushHydrationEvents?(): void; - didNotHydrateInstance?( - parentType: Type, - parentProps: Props, - parentInstance: Instance, - instance: HydratableInstance, - ): void; + clearActivityBoundary?(parentInstance: Instance, activityInstance: ActivityInstance): void; - didNotFindHydratableContainerInstance?(parentContainer: Container, type: Type, props: Props): void; + clearSuspenseBoundary?(parentInstance: Instance, suspenseInstance: SuspenseInstance): void; - didNotFindHydratableContainerTextInstance?(parentContainer: Container, text: string): void; + clearActivityBoundaryFromContainer?(container: Container, activityInstance: ActivityInstance): void; - didNotFindHydratableContainerSuspenseInstance?(parentContainer: Container): void; + clearSuspenseBoundaryFromContainer?(container: Container, suspenseInstance: SuspenseInstance): void; - didNotFindHydratableInstance?( - parentType: Type, - parentProps: Props, - parentInstance: Instance, + hideDehydratedBoundary?(suspenseInstance: SuspenseInstance): void; + + unhideDehydratedBoundary?(dehydratedInstance: SuspenseInstance | ActivityInstance): void; + + shouldDeleteUnhydratedTailInstances?(parentType: Type): boolean; + + getFirstHydratableChildWithinContainer?(parentContainer: Container): HydratableInstance | null; + + getFirstHydratableChildWithinActivityInstance?( + parentInstance: ActivityInstance, + ): HydratableInstance | null; + + getFirstHydratableChildWithinSuspenseInstance?( + parentInstance: SuspenseInstance, + ): HydratableInstance | null; + + getFirstHydratableChildWithinSingleton?( + type: Type, + singletonInstance: Instance, + currentHydratableInstance: HydratableInstance | null, + ): HydratableInstance | null; + + getNextHydratableSiblingAfterSingleton?( + type: Type, + currentHydratableInstance: HydratableInstance | null, + ): HydratableInstance | null; + + getSuspenseInstanceFallbackErrorDetails?( + instance: SuspenseInstance, + ): SuspenseInstanceFallbackErrorDetails; + + canHydrateFormStateMarker?( + instance: HydratableInstance, + inRootOrSingleton: boolean, + ): FormStateMarkerInstance | null; + + isFormStateMarkerMatching?(markerInstance: FormStateMarkerInstance): boolean; + + /** + * Replaces the removed `didNotMatchHydrated*` / `didNotFindHydratable*` dev warnings. + */ + diffHydratedPropsForDevWarnings?( + instance: Instance, type: Type, props: Props, - ): void; + hostContext: HostContext, + ): Props | null; - didNotFindHydratableTextInstance?( - parentType: Type, - parentProps: Props, - parentInstance: Instance, + diffHydratedTextForDevWarnings?( + textInstance: TextInstance, text: string, - ): void; + parentProps: Props | null, + ): string | null; + + describeHydratableInstanceForDevWarnings?( + instance: HydratableInstance, + ): string | HydratableInstanceDescription; + + validateHydratableInstance?(type: Type, props: Props, hostContext: HostContext): boolean; - didNotFindHydratableSuspenseInstance?(parentType: Type, parentProps: Props, parentInstance: Instance): void; + validateHydratableTextInstance?(text: string, hostContext: HostContext): boolean; - errorHydratingContainer?(parentContainer: Container): void; + commitHydratedSuspenseInstance?(suspenseInstance: SuspenseInstance): void; // Undocumented // https://github.com/facebook/react/pull/26722 @@ -523,20 +617,35 @@ declare namespace ReactReconciler { */ maySuspendCommit(type: Type, props: Props): boolean; + /** + * Same as `maySuspendCommit`, but called for an update to an existing instance instead of its initial mount, so it receives both the old and new props. + */ + maySuspendCommitOnUpdate(type: Type, oldProps: Props, newProps: Props): boolean; + + /** + * This method is called during a sync render to determine if the Host Component type and props are still allowed to suspend the commit. Host configs that don't want to suspend sync commits should always return `false`. + */ + maySuspendCommitInSyncRender(type: Type, props: Props): boolean; + /** * This method may be called during render if the Host Component type and props might suspend a commit. It can be used to initiate any work that might shorten the duration of a suspended commit. */ - preloadInstance(type: Type, props: Props): boolean; + preloadInstance(instance: Instance, type: Type, props: Props): boolean; /** * This method is called just before the commit phase. Use it to set up any necessary state while any Host Components that might suspend this commit are evaluated to determine if the commit must be suspended. */ - startSuspendingCommit(): void; + startSuspendingCommit(): SuspendedState; /** * This method is called after `startSuspendingCommit` for each Host Component that indicated it might suspend a commit. */ - suspendInstance(type: Type, props: Props): void; + suspendInstance(state: SuspendedState, instance: Instance, type: Type, props: Props): void; + + /** + * This method is called after `startSuspendingCommit` if there is a View Transition currently active on the root that the commit should wait to finish before proceeding. + */ + suspendOnActiveViewTransition(state: SuspendedState, rootContainer: Container): void; /** * This method is called after all `suspendInstance` calls are complete. @@ -545,9 +654,136 @@ declare namespace ReactReconciler { * * Return `(initiateCommit: Function) => Function` if the commit must be suspended. The argument to this callback will initiate the commit when called. The return value is a cancellation function that the Reconciler can use to abort the commit. */ - waitForCommitToBeReady(): + waitForCommitToBeReady( + state: SuspendedState, + timeoutOffset: number, + ): | ((initiateCommit: (...args: unknown[]) => unknown) => (...args: unknown[]) => unknown) | null; + + /** + * This method is called when a commit is suspended, to record why. It is only called when the profiler is enabled, and the result is attached to the pending commit. Return `null` if there's nothing to report. + */ + getSuspendedCommitReason(state: SuspendedState, rootContainer: Container): null | string; + + // ------------------- + // Resources + // (optional) + // ------------------- + /** + * Set this to `true` if your renderer supports Resources, e.g. hoistable ``/`