From e88b807a13ab6f664c56f97a10d0c97467e2a103 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sun, 19 May 2024 23:22:07 +1000 Subject: [PATCH] docs(ui): update field type docs & comments --- docs/contributing/frontend/WORKFLOWS.md | 21 +++++++++---------- .../store/util/validateConnectionTypes.ts | 10 ++++----- .../canvas/addControlNetToLinearGraph.ts | 2 +- .../graph/canvas/addIPAdapterToLinearGraph.ts | 2 +- .../canvas/addT2IAdapterToLinearGraph.ts | 2 +- .../nodes/util/schema/parseFieldType.ts | 2 +- 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/docs/contributing/frontend/WORKFLOWS.md b/docs/contributing/frontend/WORKFLOWS.md index e71d797b8a..533419e070 100644 --- a/docs/contributing/frontend/WORKFLOWS.md +++ b/docs/contributing/frontend/WORKFLOWS.md @@ -117,13 +117,13 @@ Stateless fields do not store their value in the node, so their field instances "Custom" fields will always be treated as stateless fields. -##### Collection and Scalar Fields +##### Single and Collection Fields -Field types have a name and two flags which may identify it as a **collection** or **collection or scalar** field. +Field types have a name and cardinality property which may identify it as a **SINGLE**, **COLLECTION** or **SINGLE_OR_COLLECTION** field. -If a field is annotated in python as a list, its field type is parsed and flagged as a **collection** type (e.g. `list[int]`). - -If it is annotated as a union of a type and list, the type will be flagged as a **collection or scalar** type (e.g. `Union[int, list[int]]`). Fields may not be unions of different types (e.g. `Union[int, list[str]]` and `Union[int, str]` are not allowed). +- If a field is annotated in python as a singular value or class, its field type is parsed as a **SINGLE** type (e.g. `int`, `ImageField`, `str`). +- If a field is annotated in python as a list, its field type is parsed as a **COLLECTION** type (e.g. `list[int]`). +- If it is annotated as a union of a type and list, the type will be parsed as a **SINGLE_OR_COLLECTION** type (e.g. `Union[int, list[int]]`). Fields may not be unions of different types (e.g. `Union[int, list[str]]` and `Union[int, str]` are not allowed). ## Implementation @@ -173,8 +173,7 @@ Field types are represented as structured objects: ```ts type FieldType = { name: string; - isCollection: boolean; - isCollectionOrScalar: boolean; + cardinality: 'SINGLE' | 'COLLECTION' | 'SINGLE_OR_COLLECTION'; }; ``` @@ -186,7 +185,7 @@ There are 4 general cases for field type parsing. When a field is annotated as a primitive values (e.g. `int`, `str`, `float`), the field type parsing is fairly straightforward. The field is represented by a simple OpenAPI **schema object**, which has a `type` property. -We create a field type name from this `type` string (e.g. `string` -> `StringField`). +We create a field type name from this `type` string (e.g. `string` -> `StringField`). The cardinality is `"SINGLE"`. ##### Complex Types @@ -200,13 +199,13 @@ We need to **dereference** the schema to pull these out. Dereferencing may requi When a field is annotated as a list of a single type, the schema object has an `items` property. They may be a schema object or reference object and must be parsed to determine the item type. -We use the item type for field type name, adding `isCollection: true` to the field type. +We use the item type for field type name. The cardinality is `"COLLECTION"`. -##### Collection or Scalar Types +##### Single or Collection Types When a field is annotated as a union of a type and list of that type, the schema object has an `anyOf` property, which holds a list of valid types for the union. -After verifying that the union has two members (a type and list of the same type), we use the type for field type name, adding `isCollectionOrScalar: true` to the field type. +After verifying that the union has two members (a type and list of the same type), we use the type for field type name, with cardinality `"SINGLE_OR_COLLECTION"`. ##### Optional Fields diff --git a/invokeai/frontend/web/src/features/nodes/store/util/validateConnectionTypes.ts b/invokeai/frontend/web/src/features/nodes/store/util/validateConnectionTypes.ts index a71ff513aa..d5dee6dbaf 100644 --- a/invokeai/frontend/web/src/features/nodes/store/util/validateConnectionTypes.ts +++ b/invokeai/frontend/web/src/features/nodes/store/util/validateConnectionTypes.ts @@ -21,11 +21,11 @@ export const validateConnectionTypes = (sourceType: FieldType, targetType: Field /** * Connection types must be the same for a connection, with exceptions: - * - CollectionItem can connect to any non-Collection - * - Non-Collections can connect to CollectionItem - * - Anything (non-Collections, Collections, CollectionOrScalar) can connect to CollectionOrScalar of the same base type - * - Generic Collection can connect to any other Collection or CollectionOrScalar - * - Any Collection can connect to a Generic Collection + * - CollectionItem can connect to any non-COLLECTION (e.g. SINGLE or SINGLE_OR_COLLECTION) + * - SINGLE can connect to CollectionItem + * - Anything (SINGLE, COLLECTION, SINGLE_OR_COLLECTION) can connect to SINGLE_OR_COLLECTION of the same base type + * - Generic CollectionField can connect to any other COLLECTION or SINGLE_OR_COLLECTION + * - Any COLLECTION can connect to a Generic Collection */ const isCollectionItemToNonCollection = sourceType.name === 'CollectionItemField' && !isCollection(targetType); diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addControlNetToLinearGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addControlNetToLinearGraph.ts index 2feba262c2..110a20e5a7 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addControlNetToLinearGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addControlNetToLinearGraph.ts @@ -29,7 +29,7 @@ export const addControlNetToLinearGraph = async ( assert(activeTabName !== 'generation', 'Tried to use addControlNetToLinearGraph on generation tab'); if (controlNets.length) { - // Even though denoise_latents' control input is collection or scalar, keep it simple and always use a collect + // Even though denoise_latents' control input is SINGLE_OR_COLLECTION, keep it simple and always use a collect const controlNetIterateNode: Invocation<'collect'> = { id: CONTROL_NET_COLLECT, type: 'collect', diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addIPAdapterToLinearGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addIPAdapterToLinearGraph.ts index e9d9bd4663..1f24463419 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addIPAdapterToLinearGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addIPAdapterToLinearGraph.ts @@ -25,7 +25,7 @@ export const addIPAdapterToLinearGraph = async ( }); if (ipAdapters.length) { - // Even though denoise_latents' ip adapter input is collection or scalar, keep it simple and always use a collect + // Even though denoise_latents' ip adapter input is SINGLE_OR_COLLECTION, keep it simple and always use a collect const ipAdapterCollectNode: Invocation<'collect'> = { id: IP_ADAPTER_COLLECT, type: 'collect', diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addT2IAdapterToLinearGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addT2IAdapterToLinearGraph.ts index 7c51d9488f..72cf9ca0f8 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addT2IAdapterToLinearGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addT2IAdapterToLinearGraph.ts @@ -28,7 +28,7 @@ export const addT2IAdaptersToLinearGraph = async ( ); if (t2iAdapters.length) { - // Even though denoise_latents' t2i adapter input is collection or scalar, keep it simple and always use a collect + // Even though denoise_latents' t2i adapter input is SINGLE_OR_COLLECTION, keep it simple and always use a collect const t2iAdapterCollectNode: Invocation<'collect'> = { id: T2I_ADAPTER_COLLECT, type: 'collect', diff --git a/invokeai/frontend/web/src/features/nodes/util/schema/parseFieldType.ts b/invokeai/frontend/web/src/features/nodes/util/schema/parseFieldType.ts index ea9bf5bce4..18dcd8fb21 100644 --- a/invokeai/frontend/web/src/features/nodes/util/schema/parseFieldType.ts +++ b/invokeai/frontend/web/src/features/nodes/util/schema/parseFieldType.ts @@ -94,7 +94,7 @@ export const parseFieldType = (schemaObject: OpenAPIV3_1SchemaOrRef): FieldType } } /** - * Handle CollectionOrScalar inputs, eg string | string[]. In OpenAPI, this is: + * Handle SINGLE_OR_COLLECTION inputs, eg string | string[]. In OpenAPI, this is: * - an `anyOf` with two items * - one is an `ArraySchemaObject` with a single `SchemaObject or ReferenceObject` of type T in its `items` * - the other is a `SchemaObject` or `ReferenceObject` of type T