main type dance, still 6 minor things to correct.

This commit is contained in:
Niels Lyngsø
2023-08-23 21:40:15 +02:00
parent d93ac1c694
commit c5e5911faf
12 changed files with 68 additions and 53 deletions

View File

@@ -16,8 +16,8 @@ export interface UmbClassMixinInterface extends UmbControllerHost, UmbController
unique?: string
): UmbObserverController<T>;
provideContext<R = unknown>(alias: string | UmbContextToken<R>, instance: R): UmbContextProviderController<R>;
consumeContext<R = unknown>(
alias: string | UmbContextToken<R>,
callback: UmbContextCallback<R>
): UmbContextConsumerController<R>;
consumeContext<BaseType = unknown, DiscriminatedType extends BaseType = never, ResultType extends BaseType = BaseType>(
alias: string | UmbContextToken<BaseType, DiscriminatedType, ResultType>,
callback: UmbContextCallback<ResultType>
): UmbContextConsumerController<BaseType, DiscriminatedType, ResultType>;
}

View File

@@ -28,10 +28,10 @@ declare class UmbClassMixinDeclaration implements UmbClassMixinInterface {
controllerAlias?: UmbControllerAlias
): UmbObserverController<T>;
provideContext<R = unknown>(alias: string | UmbContextToken<R>, instance: R): UmbContextProviderController<R>;
consumeContext<R = unknown>(
alias: string | UmbContextToken<R>,
callback: UmbContextCallback<R>
): UmbContextConsumerController<R>;
consumeContext<BaseType = unknown, DiscriminatedType extends BaseType = never, ResultType extends BaseType = BaseType>(
alias: string | UmbContextToken<BaseType, DiscriminatedType, ResultType>,
callback: UmbContextCallback<ResultType>
): UmbContextConsumerController<BaseType, DiscriminatedType, ResultType>;
hasController(controller: UmbController): boolean;
getControllers(filterMethod: (ctrl: UmbController) => boolean): UmbController[];
addController(controller: UmbController): void;
@@ -96,10 +96,10 @@ export const UmbClassMixin = <T extends ClassConstructor>(superClass: T) => {
* @return {UmbContextConsumerController} Reference to a Context Consumer Controller instance
* @memberof UmbElementMixin
*/
consumeContext<R = unknown>(
contextAlias: string | UmbContextToken<R>,
callback: UmbContextCallback<R>
): UmbContextConsumerController<R> {
consumeContext<BaseType = unknown, DiscriminatedType extends BaseType = never, ResultType extends BaseType = BaseType>(
contextAlias: string | UmbContextToken<BaseType, DiscriminatedType, ResultType>,
callback: UmbContextCallback<ResultType>
): UmbContextConsumerController<BaseType, DiscriminatedType, ResultType> {
return new UmbContextConsumerController(this, contextAlias, callback);
}
}

View File

@@ -3,7 +3,12 @@ import { UmbContextConsumer } from './context-consumer.js';
import { UmbContextCallback } from './context-request.event.js';
import type { UmbControllerHost, UmbController } from '@umbraco-cms/backoffice/controller-api';
export class UmbContextConsumerController<T = unknown> extends UmbContextConsumer<T> implements UmbController {
export class UmbContextConsumerController<
BaseType = unknown,
DiscriminatedType extends BaseType = never,
ResultType extends BaseType = keyof DiscriminatedType extends BaseType ? DiscriminatedType : BaseType
> extends UmbContextConsumer<BaseType, DiscriminatedType, ResultType> implements UmbController {
#controllerAlias = Symbol();
#host: UmbControllerHost;
@@ -11,7 +16,7 @@ export class UmbContextConsumerController<T = unknown> extends UmbContextConsume
return this.#controllerAlias;
}
constructor(host: UmbControllerHost, contextAlias: string | UmbContextToken<T>, callback: UmbContextCallback<T>) {
constructor(host: UmbControllerHost, contextAlias: string | UmbContextToken<BaseType, DiscriminatedType, ResultType>, callback: UmbContextCallback<ResultType>) {
super(host.getHostElement(), contextAlias, callback);
this.#host = host;
host.addController(this);

View File

@@ -11,12 +11,15 @@ import { UmbContextRequestEventImplementation, UmbContextCallback } from './cont
* @export
* @class UmbContextConsumer
*/
export class UmbContextConsumer<BaseType = unknown, DiscriminatedType extends BaseType = BaseType> {
#callback?: UmbContextCallback<DiscriminatedType>;
#promise?: Promise<DiscriminatedType>;
#promiseResolver?: (instance: DiscriminatedType) => void;
export class UmbContextConsumer<
BaseType = unknown,
DiscriminatedType extends BaseType = never,
ResultType extends BaseType = keyof DiscriminatedType extends BaseType ? DiscriminatedType : BaseType> {
#callback?: UmbContextCallback<ResultType>;
#promise?: Promise<ResultType>;
#promiseResolver?: (instance: ResultType) => void;
#instance?: DiscriminatedType;
#instance?: ResultType;
get instance() {
return this.#instance;
}
@@ -34,8 +37,8 @@ export class UmbContextConsumer<BaseType = unknown, DiscriminatedType extends Ba
*/
constructor(
protected hostElement: EventTarget,
contextAlias: string | UmbContextToken<BaseType, DiscriminatedType>,
callback?: UmbContextCallback<DiscriminatedType>
contextAlias: string | UmbContextToken<BaseType, DiscriminatedType, ResultType>,
callback?: UmbContextCallback<ResultType>
) {
this.#contextAlias = contextAlias.toString();
this.#callback = callback;
@@ -55,14 +58,14 @@ export class UmbContextConsumer<BaseType = unknown, DiscriminatedType extends Ba
if(this.#discriminator) {
// Notice if discriminator returns false, we do not want to setInstance.
if(this.#discriminator(instance)) {
this.setInstance(instance);
this.setInstance(instance as unknown as ResultType);
}
} else {
this.setInstance(instance as DiscriminatedType);
this.setInstance(instance as ResultType);
}
};
protected setInstance(instance: DiscriminatedType) {
protected setInstance(instance: ResultType) {
this.#instance = instance;
this.#callback?.(instance);
if (instance !== undefined) {
@@ -74,7 +77,7 @@ export class UmbContextConsumer<BaseType = unknown, DiscriminatedType extends Ba
public asPromise() {
return (
this.#promise ??
(this.#promise = new Promise<DiscriminatedType>((resolve) => {
(this.#promise = new Promise<ResultType>((resolve) => {
this.#instance ? resolve(this.#instance) : (this.#promiseResolver = resolve);
}))
);

View File

@@ -9,9 +9,9 @@ export type UmbContextCallback<T> = (instance: T) => void;
* @export
* @interface UmbContextRequestEvent
*/
export interface UmbContextRequestEvent<T = unknown> extends Event {
readonly contextAlias: string | UmbContextToken<T>;
readonly callback: UmbContextCallback<T>;
export interface UmbContextRequestEvent<ResultType = unknown> extends Event {
readonly contextAlias: string | UmbContextToken<unknown, any, ResultType>;
readonly callback: UmbContextCallback<ResultType>;
}
/**
@@ -20,10 +20,10 @@ export interface UmbContextRequestEvent<T = unknown> extends Event {
* @extends {Event}
* @implements {UmbContextRequestEvent}
*/
export class UmbContextRequestEventImplementation<T = unknown> extends Event implements UmbContextRequestEvent<T> {
export class UmbContextRequestEventImplementation<ResultType = unknown> extends Event implements UmbContextRequestEvent<ResultType> {
public constructor(
public readonly contextAlias: string | UmbContextToken<T>,
public readonly callback: UmbContextCallback<T>
public readonly contextAlias: string | UmbContextToken<any, any, ResultType>,
public readonly callback: UmbContextCallback<ResultType>
) {
super(umbContextRequestEventType, { bubbles: true, composed: true, cancelable: true });
}

View File

@@ -2,14 +2,18 @@ import { UmbContextToken } from '../token/context-token.js';
import { UmbContextProvider } from './context-provider.js';
import type { UmbControllerHost, UmbController } from '@umbraco-cms/backoffice/controller-api';
export class UmbContextProviderController<T = unknown> extends UmbContextProvider implements UmbController {
export class UmbContextProviderController<
BaseType = unknown,
DiscriminatorType extends BaseType = never,
ResultType extends BaseType = keyof DiscriminatorType extends BaseType ? DiscriminatorType : BaseType
> extends UmbContextProvider<BaseType, DiscriminatorType, ResultType> implements UmbController {
#host: UmbControllerHost;
public get controllerAlias() {
return this._contextAlias.toString();
}
constructor(host: UmbControllerHost, contextAlias: string | UmbContextToken<T>, instance: T) {
constructor(host: UmbControllerHost, contextAlias: string | UmbContextToken<BaseType, DiscriminatorType, ResultType>, instance: ResultType) {
super(host.getHostElement(), contextAlias, instance);
this.#host = host;

View File

@@ -13,7 +13,7 @@ import {
* @export
* @class UmbContextProvider
*/
export class UmbContextProvider {
export class UmbContextProvider<BaseType = unknown, DiscriminatorType extends BaseType = never, ResultType extends BaseType = keyof DiscriminatorType extends BaseType ? DiscriminatorType : BaseType> {
protected hostElement: EventTarget;
protected _contextAlias: string;
@@ -35,7 +35,7 @@ export class UmbContextProvider {
* @param {*} instance
* @memberof UmbContextProvider
*/
constructor(hostElement: EventTarget, contextAlias: string | UmbContextToken, instance: unknown) {
constructor(hostElement: EventTarget, contextAlias: string | UmbContextToken<BaseType, DiscriminatorType, ResultType>, instance: ResultType) {
this.hostElement = hostElement;
this._contextAlias = contextAlias.toString();
this.#instance = instance;

View File

@@ -1,7 +1,7 @@
export type UmbContextDiscriminator<BaseType, DiscriminatorResult extends BaseType = BaseType> = (instance: BaseType) => instance is DiscriminatorResult;
export type UmbContextDiscriminator<BaseType, DiscriminatorResult extends BaseType> = (instance: BaseType) => instance is DiscriminatorResult;
export class UmbContextToken<BaseType = unknown, DiscriminatedType extends BaseType = BaseType> {
export class UmbContextToken<BaseType = unknown, DiscriminatedType extends BaseType = never, ResultType extends BaseType = keyof DiscriminatedType extends object ? DiscriminatedType : BaseType> {
#discriminator: UmbContextDiscriminator<BaseType, DiscriminatedType> | undefined;
/**
@@ -13,7 +13,7 @@ export class UmbContextToken<BaseType = unknown, DiscriminatedType extends BaseT
* @example `typeof MyToken.TYPE`
* @returns undefined
*/
readonly TYPE: DiscriminatedType = undefined as never;
readonly TYPE: ResultType = undefined as never;
/**
* @param alias Unique identifier for the token

View File

@@ -25,10 +25,10 @@ export declare class UmbElement extends UmbControllerHostElement {
unique?: string
): UmbObserverController<T>;
provideContext<R = unknown>(alias: string | UmbContextToken<R>, instance: R): UmbContextProviderController<R>;
consumeContext<R = unknown>(
alias: string | UmbContextToken<R>,
callback: UmbContextCallback<R>
): UmbContextConsumerController<R>;
consumeContext<BaseType = unknown, DiscriminatedType extends BaseType = never, ResultType extends BaseType = BaseType>(
alias: string | UmbContextToken<BaseType, DiscriminatedType, ResultType>,
callback: UmbContextCallback<ResultType>
): UmbContextConsumerController<BaseType, DiscriminatedType, ResultType>;
}
export const UmbElementMixin = <T extends HTMLElementConstructor>(superClass: T) => {
@@ -64,10 +64,10 @@ export const UmbElementMixin = <T extends HTMLElementConstructor>(superClass: T)
* @return {UmbContextConsumerController} Reference to a Context Consumer Controller instance
* @memberof UmbElementMixin
*/
consumeContext<R = unknown>(
alias: string | UmbContextToken<R>,
callback: UmbContextCallback<R>
): UmbContextConsumerController<R> {
consumeContext<BaseType = unknown, DiscriminatedType extends BaseType = never, ResultType extends BaseType = BaseType>(
alias: string | UmbContextToken<BaseType, DiscriminatedType, ResultType>,
callback: UmbContextCallback<ResultType>
): UmbContextConsumerController<BaseType, DiscriminatedType, ResultType> {
return new UmbContextConsumerController(this, alias, callback);
}
}

View File

@@ -3,6 +3,7 @@ import { UmbEntityWorkspaceContextInterface, UmbWorkspaceContext } from '@umbrac
import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { appendToFrozenArray, UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export class UmbDataTypeWorkspaceContext
extends UmbWorkspaceContext<UmbDataTypeRepository, DataTypeResponseModel>
@@ -95,3 +96,8 @@ export class UmbDataTypeWorkspaceContext
this.#data.complete();
}
}
export const UMB_DATA_TYPE_WORKSPACE_CONTEXT = new UmbContextToken<UmbEntityWorkspaceContextInterface, UmbDataTypeWorkspaceContext>(
'UmbWorkspaceContext',
(context): context is UmbDataTypeWorkspaceContext => context.getEntityType?.() === 'data-type'
);

View File

@@ -1,7 +1,6 @@
import { UmbDataTypeWorkspaceContext } from '../../data-type-workspace.context.js';
import { UMB_DATA_TYPE_WORKSPACE_CONTEXT, UmbDataTypeWorkspaceContext } from '../../data-type-workspace.context.js';
import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui';
import { css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import {
UmbModalManagerContext,
UMB_MODAL_MANAGER_CONTEXT_TOKEN,
@@ -47,9 +46,8 @@ export class UmbDataTypeDetailsWorkspaceViewEditElement
this._modalContext = instance;
});
// TODO: Figure out if this is the best way to consume a context or if it could be strongly typed using UmbContextToken
this.consumeContext(UMB_WORKSPACE_CONTEXT, (_instance) => {
this._workspaceContext = _instance as UmbDataTypeWorkspaceContext;
this.consumeContext(UMB_DATA_TYPE_WORKSPACE_CONTEXT, (_instance) => {
this._workspaceContext = _instance;
this._observeDataType();
});
}

View File

@@ -2,6 +2,5 @@ import { IUmbAuth } from './auth.interface.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export const UMB_AUTH = new UmbContextToken<IUmbAuth>(
'UmbAuth',
'An instance of UmbAuthFlow that should be shared across the app.'
'UmbAuth'
);