/*! * Copyright (c) Microsoft Corporation and contributors. All rights reserved. * Licensed under the MIT License. */ import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal"; import type { IdCreationRange } from "@fluidframework/id-compressor/internal"; import type { FluidDataStoreMessage, IAttachMessage, IEnvelope, InboundAttachMessage, } from "@fluidframework/runtime-definitions/internal"; import type { IDataStoreAliasMessage } from "./dataStore.js"; import type { GarbageCollectionMessage } from "./gc/index.js"; import type { IChunkedOp } from "./opLifecycle/index.js"; import type { IDocumentSchemaChangeMessageIncoming, IDocumentSchemaChangeMessageOutgoing, } from "./summary/index.js"; /** * @legacy @beta */ export enum ContainerMessageType { // An op to be delivered to store FluidDataStoreOp = "component", // Creates a new store Attach = "attach", // Chunked operation. ChunkedOp = "chunkedOp", // Signifies that a blob has been attached and should not be garbage collected by storage BlobAttach = "blobAttach", // Ties our new clientId to our old one on reconnect Rejoin = "rejoin", // Sets the alias of a root data store Alias = "alias", /** * An op containing an IdRange of Ids allocated using the runtime's IdCompressor since * the last allocation op was sent. * See the {@link https://github.com/microsoft/FluidFramework/blob/main/packages/runtime/id-compressor/README.md|IdCompressor README} for more details. */ IdAllocation = "idAllocation", /** * An op that changes document schema */ DocumentSchemaChange = "schema", /** * Garbage collection specific op. This is sent by the summarizer client when GC runs. It's used to synchronize GC * state across all clients. */ GC = "GC", } /** * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime. * Message type are differentiated via a `type` string and contain different contents depending on their type. * * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here. * This way stringified values can be compared. * * @internal */ export interface TypedContainerRuntimeMessage { /** * Type of the op, within the ContainerRuntime's domain */ type: TType; /** * Domain-specific contents, interpreted according to the type */ contents: TContents; } /** * @internal * @privateRemarks exported per ContainerRuntime export for testing purposes */ export type ContainerRuntimeDataStoreOpMessage = TypedContainerRuntimeMessage< ContainerMessageType.FluidDataStoreOp, IEnvelope >; export type InboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage< ContainerMessageType.Attach, InboundAttachMessage >; /** * @internal * @privateRemarks exported per ContainerRuntime export for testing purposes */ export type OutboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage< ContainerMessageType.Attach, IAttachMessage >; export type ContainerRuntimeChunkedOpMessage = TypedContainerRuntimeMessage< ContainerMessageType.ChunkedOp, IChunkedOp >; export type ContainerRuntimeBlobAttachMessage = TypedContainerRuntimeMessage< ContainerMessageType.BlobAttach, undefined >; export type ContainerRuntimeRejoinMessage = TypedContainerRuntimeMessage< ContainerMessageType.Rejoin, undefined >; /** * @internal * @privateRemarks exported per ContainerRuntime export for testing purposes */ export type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage< ContainerMessageType.Alias, IDataStoreAliasMessage >; export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage< ContainerMessageType.IdAllocation, IdCreationRange >; export type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage< ContainerMessageType.GC, GarbageCollectionMessage >; export type InboundContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage< ContainerMessageType.DocumentSchemaChange, IDocumentSchemaChangeMessageIncoming >; export type OutboundContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage< ContainerMessageType.DocumentSchemaChange, IDocumentSchemaChangeMessageOutgoing >; /** * Represents an unrecognized TypedContainerRuntimeMessage, e.g. a message from a future version of the container runtime. * @internal */ export interface UnknownContainerRuntimeMessage { /** * Invalid type of the op, within the ContainerRuntime's domain. This value should never exist at runtime. * This is useful for type narrowing but should never be used as an actual message type at runtime. * Actual value will not be "__unknown...", but the type `Exclude` is not supported. */ type: "__unknown_container_message_type__never_use_as_value__"; /** * Domain-specific contents, but not decipherable by an unknown op. */ contents: unknown; } /** * A {@link TypedContainerRuntimeMessage} that is received from the server and will be processed by the container runtime. */ export type InboundContainerRuntimeMessage = | ContainerRuntimeDataStoreOpMessage | InboundContainerRuntimeAttachMessage | ContainerRuntimeChunkedOpMessage | ContainerRuntimeBlobAttachMessage | ContainerRuntimeRejoinMessage | ContainerRuntimeAliasMessage | ContainerRuntimeIdAllocationMessage | ContainerRuntimeGCMessage | InboundContainerRuntimeDocumentSchemaMessage // Inbound messages may include unknown types from other clients, so we include that as a special case here | UnknownContainerRuntimeMessage; /** * A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime, eventually to be sent to the ordering service. * These are messages generated by the local runtime, before the outbox's op virtualization step. */ export type LocalContainerRuntimeMessage = | ContainerRuntimeDataStoreOpMessage | OutboundContainerRuntimeAttachMessage | ContainerRuntimeBlobAttachMessage | ContainerRuntimeRejoinMessage | ContainerRuntimeAliasMessage | ContainerRuntimeIdAllocationMessage | ContainerRuntimeGCMessage | OutboundContainerRuntimeDocumentSchemaMessage // In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type | UnknownContainerRuntimeMessage; /** * An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc * promoted up to the outer object */ export type InboundSequencedContainerRuntimeMessage = Omit< ISequencedDocumentMessage, "type" | "contents" > & InboundContainerRuntimeMessage;