import { ModelId } from "../../Traits/ModelReference"; import ModelTraits from "../../Traits/ModelTraits"; import Trait from "../../Traits/Trait"; import TraitsConstructor from "../../Traits/TraitsConstructor"; import Terria from "../Terria"; import ModelPropertiesFromTraits from "./ModelPropertiesFromTraits"; import StratumFromTraits from "./StratumFromTraits"; export interface ModelConstructor { new ( uniqueId: string | undefined, terria: Terria, sourceReference?: BaseModel, strata?: Map> ): T; prototype: T; TraitsClass: TraitsConstructor; } export type ModelConstructorParameters = ConstructorParameters< ModelConstructor >; export abstract class BaseModel { abstract get type(): string; abstract get traits(): { [id: string]: Trait; }; abstract get TraitsClass(): TraitsConstructor; abstract get knownContainerUniqueIds(): string[]; abstract get completeKnownContainerUniqueIds(): string[]; abstract get strata(): Map>; constructor( readonly uniqueId: string | undefined, readonly terria: Terria, /** * The model whose {@link ReferenceMixin} references this model. * This instance will also be that model's {@link ReferenceMixin#target} * property. If undefined, this model is not the target of a reference. */ readonly sourceReference: BaseModel | undefined ) {} dispose() {} abstract duplicateModel( newId: ModelId, sourceReference?: BaseModel ): BaseModel; abstract get strataTopToBottom(): ReadonlyMap< string, StratumFromTraits >; abstract get strataBottomToTop(): ReadonlyMap< string, StratumFromTraits >; abstract setTrait(stratumId: string, trait: unknown, value: unknown): void; abstract getTrait(stratumId: string, trait: unknown): unknown; } export type ArrayElementTypes = { [P in keyof T]-?: NonNullable extends ArrayLike ? E extends ModelTraits ? E : never : never; }; export interface ModelInterface { readonly type: string; readonly traits: { [id: string]: Trait; }; readonly TraitsClass: TraitsConstructor; readonly strata: Map>; readonly terria: Terria; readonly uniqueId: string | undefined; readonly knownContainerUniqueIds: string[]; readonly completeKnownContainerUniqueIds: string[]; /** * The model whose {@link ReferenceMixin} references this model. * This instance will also be that model's {@link ReferenceMixin#target} * property. If undefined, this model is not the target of a reference. */ readonly sourceReference: BaseModel | undefined; readonly strataTopToBottom: ReadonlyMap>; readonly strataBottomToTop: ReadonlyMap>; dispose(): void; duplicateModel(newId: ModelId, sourceReference?: BaseModel): this; setTrait>( stratumId: string, trait: Key, value: StratumFromTraits[Key] ): void; getTrait>( stratumId: string, trait: Key ): StratumFromTraits[Key]; /** * Adds a new object to an {@link objectArrayTrait}. * * If no `objectId` is provided, the object will be placed at the end of the array (across all strata). This will take `isRemoval` and `idProperty="index"`into account. * * @param stratumId The ID of the stratum in which to add the object. * @param trait The name of the {@link objectArrayTrait} property. * @param objectId The ID of the new object. * @returns The new object, or undefined if the object still does not exist because a stratum above the specified one has removed it. */ addObject>( stratumId: string, trait: Key, objectId?: string | undefined ): Model[Key]> | undefined; } type Model = ModelInterface & ModelPropertiesFromTraits; export default Model;