UNPKG

@tldraw/store

Version:

tldraw infinite canvas SDK (store).

8 lines (7 loc) 4.58 kB
{ "version": 3, "sources": ["../../src/lib/BaseRecord.ts"], "sourcesContent": ["/**\n * A branded string type that represents a unique identifier for a record.\n * The brand ensures type safety by preventing mixing of IDs between different record types.\n *\n * @example\n * ```ts\n * // Define a Book record\n * interface Book extends BaseRecord<'book', RecordId<Book>> {\n * title: string\n * author: string\n * }\n *\n * const bookId: RecordId<Book> = 'book:abc123' as RecordId<Book>\n * const authorId: RecordId<Author> = 'author:xyz789' as RecordId<Author>\n *\n * // TypeScript prevents mixing different record ID types\n * // bookId = authorId // Type error!\n * ```\n *\n * @public\n */\nexport type RecordId<R extends UnknownRecord> = string & { __type__: R }\n\n/**\n * Utility type that extracts the ID type from a record type.\n * This is useful when you need to work with record IDs without having the full record type.\n *\n * @example\n * ```ts\n * interface Book extends BaseRecord<'book', RecordId<Book>> {\n * title: string\n * author: string\n * }\n *\n * // Extract the ID type from the Book record\n * type BookId = IdOf<Book> // RecordId<Book>\n *\n * function findBook(id: IdOf<Book>): Book | undefined {\n * return store.get(id)\n * }\n * ```\n *\n * @public\n */\nexport type IdOf<R extends UnknownRecord> = R['id']\n\n/**\n * The base record interface that all records in the store must extend.\n * This interface provides the fundamental structure required for all records: a unique ID and a type name.\n * The type parameters ensure type safety and prevent mixing of different record types.\n *\n * @example\n * ```ts\n * // Define a Book record that extends BaseRecord\n * interface Book extends BaseRecord<'book', RecordId<Book>> {\n * title: string\n * author: string\n * publishedYear: number\n * }\n *\n * // Define an Author record\n * interface Author extends BaseRecord<'author', RecordId<Author>> {\n * name: string\n * birthYear: number\n * }\n *\n * // Usage with RecordType\n * const Book = createRecordType<Book>('book', { scope: 'document' })\n * const book = Book.create({\n * title: '1984',\n * author: 'George Orwell',\n * publishedYear: 1949\n * })\n * // Results in: { id: 'book:abc123', typeName: 'book', title: '1984', ... }\n * ```\n *\n * @public\n */\nexport interface BaseRecord<TypeName extends string, Id extends RecordId<UnknownRecord>> {\n\treadonly id: Id\n\treadonly typeName: TypeName\n}\n\n/**\n * A generic type representing any record that extends BaseRecord.\n * This is useful for type constraints when you need to work with records of unknown types,\n * but still want to ensure they follow the BaseRecord structure.\n *\n * @example\n * ```ts\n * // Function that works with any type of record\n * function logRecord(record: UnknownRecord): void {\n * console.log(`Record ${record.id} of type ${record.typeName}`)\n * }\n *\n * // Can be used with any record type\n * const book: Book = { id: 'book:123' as RecordId<Book>, typeName: 'book', title: '1984' }\n * const author: Author = { id: 'author:456' as RecordId<Author>, typeName: 'author', name: 'Orwell' }\n *\n * logRecord(book) // \"Record book:123 of type book\"\n * logRecord(author) // \"Record author:456 of type author\"\n * ```\n *\n * @public\n */\nexport type UnknownRecord = BaseRecord<string, RecordId<UnknownRecord>>\n\n/**\n * Type guard function that checks if an unknown value is a valid record.\n * A valid record must be an object with both `id` and `typeName` properties.\n *\n * @param record - The unknown value to check\n * @returns `true` if the value is a valid UnknownRecord, `false` otherwise\n *\n * @example\n * ```ts\n * const maybeRecord: unknown = { id: 'book:123', typeName: 'book', title: '1984' }\n * const notARecord: unknown = { title: '1984', author: 'Orwell' }\n * const nullValue: unknown = null\n *\n * if (isRecord(maybeRecord)) {\n * // TypeScript now knows maybeRecord is UnknownRecord\n * console.log(maybeRecord.id) // 'book:123'\n * console.log(maybeRecord.typeName) // 'book'\n * }\n *\n * console.log(isRecord(maybeRecord)) // true\n * console.log(isRecord(notARecord)) // false (missing id and typeName)\n * console.log(isRecord(nullValue)) // false\n * ```\n *\n * @public\n */\nexport function isRecord(record: unknown): record is UnknownRecord {\n\treturn typeof record === 'object' && record !== null && 'id' in record && 'typeName' in record\n}\n"], "mappings": "AAqIO,SAAS,SAAS,QAA0C;AAClE,SAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,QAAQ,UAAU,cAAc;AACzF;", "names": [] }