UNPKG

@veltdev/sdk

Version:

Velt is an SDK to add collaborative features to your product within minutes. Example: Comments like Figma, Frame.io, Google docs or sheets, Recording like Loom, Huddles like Slack and much more.

178 lines (177 loc) 7.62 kB
import { Observable } from 'rxjs'; import { BaseMetadata } from './base-metadata.data.model'; import { User } from './user.data.model'; /** * Feature types that can generate activities. */ export type ActivityFeatureType = 'comment' | 'reaction' | 'recorder' | 'crdt' | 'custom'; /** * Comment action type constants following the `entity_type.action` naming pattern. * Annotation-level actions use `comment_annotation.*`, comment-level use `comment.*`. */ export declare const CommentActivityActionTypes: { readonly ANNOTATION_ADD: "comment_annotation.add"; readonly ANNOTATION_DELETE: "comment_annotation.delete"; readonly COMMENT_ADD: "comment.add"; readonly COMMENT_UPDATE: "comment.update"; readonly COMMENT_DELETE: "comment.delete"; readonly STATUS_CHANGE: "comment_annotation.status_change"; readonly PRIORITY_CHANGE: "comment_annotation.priority_change"; readonly ASSIGN: "comment_annotation.assign"; readonly ACCESS_MODE_CHANGE: "comment_annotation.access_mode_change"; readonly CUSTOM_LIST_CHANGE: "comment_annotation.custom_list_change"; readonly APPROVE: "comment_annotation.approve"; readonly ACCEPT: "comment.accept"; readonly REJECT: "comment.reject"; readonly REACTION_ADD: "comment.reaction_add"; readonly REACTION_DELETE: "comment.reaction_delete"; readonly SUBSCRIBE: "comment_annotation.subscribe"; readonly UNSUBSCRIBE: "comment_annotation.unsubscribe"; }; export type CommentActivityActionType = typeof CommentActivityActionTypes[keyof typeof CommentActivityActionTypes]; /** * Recorder action type constants following the `recording.*` naming pattern. */ export declare const RecorderActivityActionTypes: { readonly RECORDING_ADD: "recording.add"; readonly RECORDING_DELETE: "recording.delete"; }; export type RecorderActivityActionType = typeof RecorderActivityActionTypes[keyof typeof RecorderActivityActionTypes]; /** * Reaction action type constants following the `reaction.*` naming pattern. */ export declare const ReactionActivityActionTypes: { readonly REACTION_ADD: "reaction.add"; readonly REACTION_DELETE: "reaction.delete"; }; export type ReactionActivityActionType = typeof ReactionActivityActionTypes[keyof typeof ReactionActivityActionTypes]; /** * CRDT action type constants following the `crdt.*` naming pattern. */ export declare const CrdtActivityActionTypes: { readonly EDITOR_EDIT: "crdt.editor_edit"; }; export type CrdtActivityActionType = typeof CrdtActivityActionTypes[keyof typeof CrdtActivityActionTypes]; /** * Represents a single from/to change pair. * `from` is always present (null for 'added' events) for uniform structure. */ export interface ActivityChange<T = unknown> { from?: T | null; to?: T | null; } /** * Dynamic change tracking. Keys are domain-specific (e.g., 'status', 'commentText', 'assignedTo'). * No fixed keys — activities span multiple features. */ export interface ActivityChanges { [key: string]: ActivityChange | undefined; } /** * Metadata for activity records. Extends BaseMetadata with denormalized IDs * for efficient querying at the organization level. */ export declare class ActivityMetadata extends BaseMetadata { [key: string]: any; } /** * Core activity record representing a single activity event. * * @typeParam TEntity - Type of the parent entity snapshot (e.g., CommentAnnotation) * @typeParam TTarget - Type of the sub-entity snapshot (e.g., Comment) */ export declare class ActivityRecord<TEntity = unknown, TTarget = unknown> { /** Auto-generated unique ID */ id: string; /** Feature that generated this activity */ featureType: ActivityFeatureType; /** Action that occurred, following `entity_type.action` pattern */ actionType: string; /** Event type that occurred */ eventType?: string; /** User who performed the action */ actionUser: User; /** Server timestamp (set by backend) */ timestamp: number; /** Denormalized IDs for querying */ metadata: ActivityMetadata; /** ID of the parent entity (annotationId, recordingId, etc.) */ targetEntityId: string; /** ID of the sub-entity acted on (commentId within annotation, null for entity-level actions) */ targetSubEntityId?: string | null; /** Linear-style from/to change pairs */ changes?: ActivityChanges; /** Full parent entity snapshot at time of action */ entityData?: TEntity; /** Sub-entity snapshot (or user-provided data for custom activities) */ entityTargetData?: TTarget; /** Display message template — ONLY for custom activities */ displayMessageTemplate?: string; /** Template variable values — ONLY for custom activities */ displayMessageTemplateData?: Record<string, unknown>; /** Computed display message (generated client-side, never stored in Firestore) */ displayMessage?: string; /** Icon URL or identifier for display */ actionIcon?: string; /** If true, this activity cannot be updated or deleted via REST API */ immutable?: boolean; } /** * Configuration for subscribing to activities. * Behavior is determined by the props passed: * - No config → org-wide * - documentIds → specific documents * - currentDocumentOnly → current document only */ export interface ActivitySubscribeConfig { /** Subscribe to activities for a specific organization (defaults to current org) */ organizationId?: string; /** Subscribe to activities for specific document IDs */ documentIds?: string[]; /** Subscribe to activities for the current document only (auto-switches on setDocument) */ currentDocumentOnly?: boolean; /** Only fetch activities from the last N days (default: 30) */ maxDays?: number; /** Allowlist: only include activities with these feature types */ featureTypes?: ActivityFeatureType[]; /** Disallowlist: exclude activities with these feature types (ignored if featureTypes is set) */ excludeFeatureTypes?: ActivityFeatureType[]; /** Allowlist: only include activities with these action types */ actionTypes?: string[]; /** Disallowlist: exclude activities with these action types (ignored if actionTypes is set) */ excludeActionTypes?: string[]; /** Allowlist: only include activities by these user IDs */ userIds?: string[]; /** Disallowlist: exclude activities by these user IDs (ignored if userIds is set) */ excludeUserIds?: string[]; } /** * Represents an active activity subscription. * Returned by `activityService.subscribe()`. */ export interface ActivitySubscription { /** Observable stream of activities for this subscription's scope. null = not yet loaded. */ getActivities$(): Observable<ActivityRecord[] | null>; /** Unsubscribe and clean up this subscription */ unsubscribe(): void; } /** * Data required to create an activity. * Used for all activity types: comment, reaction, recorder, custom, etc. */ export interface CreateActivityData<TEntity = unknown, TTarget = unknown> { featureType: ActivityFeatureType; actionType: string; eventType?: string; targetEntityId: string; targetSubEntityId?: string | null; changes?: ActivityChanges; entityData?: TEntity; entityTargetData?: TTarget; /** Icon URL or identifier — typically used for custom activities */ actionIcon?: string; /** Display message template — only for custom activities */ displayMessageTemplate?: string; /** Template variable values — only for custom activities */ displayMessageTemplateData?: Record<string, unknown>; }