@tldraw/tlschema
Version:
tldraw infinite canvas SDK (schema).
8 lines (7 loc) • 9.13 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/records/TLAsset.ts"],
"sourcesContent": ["import {\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { mapObjectMapValues } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { createAssetValidator, TLBaseAsset } from '../assets/TLBaseAsset'\nimport { TLBookmarkAsset } from '../assets/TLBookmarkAsset'\nimport { TLImageAsset } from '../assets/TLImageAsset'\nimport { TLVideoAsset } from '../assets/TLVideoAsset'\nimport { SchemaPropsInfo } from '../createTLSchema'\nimport { TLPropsMigrations } from '../recordsWithProps'\nimport { ExtractShapeByProps } from './TLShape'\n\n/**\n * The default set of asset types that are available in the editor.\n *\n * @example\n * ```ts\n * const imageAsset: TLDefaultAsset = {\n * id: 'asset:image123',\n * typeName: 'asset',\n * type: 'image',\n * props: {\n * src: 'https://example.com/image.jpg',\n * w: 800,\n * h: 600,\n * mimeType: 'image/jpeg',\n * isAnimated: false,\n * name: 'image.jpg',\n * },\n * meta: {},\n * }\n * ```\n *\n * @public\n */\nexport type TLDefaultAsset = TLImageAsset | TLVideoAsset | TLBookmarkAsset\n\n/**\n * A type for an asset that is available in the editor but whose type is\n * unknown\u2014either one of the editor's default assets or else a custom asset.\n *\n * @public\n */\nexport type TLUnknownAsset = TLBaseAsset<string, object>\n\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface TLGlobalAssetPropsMap {}\n\n/** @public */\n// prettier-ignore\nexport type TLIndexedAssets = {\n\t[K in keyof TLGlobalAssetPropsMap | TLDefaultAsset['type'] as K extends TLDefaultAsset['type']\n\t\t? K extends keyof TLGlobalAssetPropsMap\n\t\t\t? TLGlobalAssetPropsMap[K] extends null | undefined\n\t\t\t\t? never\n\t\t\t\t: K\n\t\t\t: K\n\t\t: K]: K extends TLDefaultAsset['type']\n\t\t? K extends keyof TLGlobalAssetPropsMap\n\t\t\t? TLBaseAsset<K, TLGlobalAssetPropsMap[K]>\n\t\t\t: Extract<TLDefaultAsset, { type: K }>\n\t\t: TLBaseAsset<K, TLGlobalAssetPropsMap[K & keyof TLGlobalAssetPropsMap]>\n}\n\n/**\n * The set of all assets that are available in the editor.\n *\n * This is the primary asset type used throughout tldraw. It includes both the\n * built-in default assets and any custom assets registered via\n * {@link TLGlobalAssetPropsMap} augmentation.\n *\n * You can use this type without a type argument to work with any asset, or pass\n * a specific asset type string (e.g., `'image'`, `'video'`, `'bookmark'`) to\n * narrow down to that specific asset type.\n *\n * @example\n * ```ts\n * // Register a custom asset type\n * declare module '@tldraw/tlschema' {\n * interface TLGlobalAssetPropsMap {\n * file: { name: string; size: number; mimeType: string; src: string | null }\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLAsset<K extends keyof TLIndexedAssets = keyof TLIndexedAssets> = TLIndexedAssets[K]\n\n/**\n * Migration version identifiers for asset record schema evolution.\n * Each version represents a breaking change that requires data migration.\n *\n * @example\n * ```ts\n * // Check if a migration is needed\n * const needsMigration = currentVersion < assetVersions.AddMeta\n * ```\n *\n * @public\n */\nexport const assetVersions = createMigrationIds('com.tldraw.asset', {\n\tAddMeta: 1,\n} as const)\n\n/**\n * Migration sequence for evolving asset record structure over time.\n * Handles converting asset records from older schema versions to current format.\n *\n * @example\n * ```ts\n * // Migration is applied automatically when loading old documents\n * const migratedStore = migrator.migrateStoreSnapshot({\n * schema: oldSchema,\n * store: oldStoreSnapshot,\n * })\n * ```\n *\n * @public\n */\nexport const assetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset',\n\trecordType: 'asset',\n\tsequence: [\n\t\t{\n\t\t\tid: assetVersions.AddMeta,\n\t\t\tup: (record) => {\n\t\t\t\t;(record as any).meta = {}\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * Partial type for TLAsset allowing optional properties except id and type.\n * Useful for creating or updating assets where not all properties need to be specified.\n *\n * @example\n * ```ts\n * // Create a partial asset for updating\n * const partialAsset: TLAssetPartial<TLImageAsset> = {\n * id: 'asset:image123',\n * type: 'image',\n * props: {\n * w: 800, // Only updating width\n * },\n * }\n *\n * // Use in asset updates\n * editor.updateAssets([partialAsset])\n * ```\n *\n * @public\n */\nexport type TLAssetPartial<T extends TLAsset = TLAsset> = T extends T\n\t? {\n\t\t\tid: TLAssetId\n\t\t\ttype: T['type']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t} & Partial<Omit<T, 'type' | 'id' | 'props' | 'meta'>>\n\t: never\n\n/**\n * Creates the record type definition for assets based on registered asset schemas.\n * This function follows the same pattern as `createShapeRecordType` and `createBindingRecordType`.\n *\n * @param assets - Record of asset type names to their schema configuration\n * @returns A configured record type for assets with validation\n *\n * @example\n * ```ts\n * const AssetRecordType = createAssetRecordType({\n * image: { migrations: imageAssetMigrations, props: imageAssetProps },\n * video: { migrations: videoAssetMigrations, props: videoAssetProps },\n * bookmark: { migrations: bookmarkAssetMigrations, props: bookmarkAssetProps },\n * })\n * ```\n *\n * @internal\n */\nexport function createAssetRecordType(assets: Record<string, SchemaPropsInfo>) {\n\treturn createRecordType('asset', {\n\t\tscope: 'document',\n\t\tvalidator: T.model(\n\t\t\t'asset',\n\t\t\tT.union(\n\t\t\t\t'type',\n\t\t\t\tmapObjectMapValues(assets, (type, { props, meta }) =>\n\t\t\t\t\tcreateAssetValidator(type, props, meta)\n\t\t\t\t)\n\t\t\t)\n\t\t),\n\t}).withDefaultProperties(() => ({\n\t\tmeta: {},\n\t}))\n}\n\n/**\n * Record type definition for default TLAsset records with document scope and default metadata.\n *\n * @public\n */\nexport const AssetRecordType = createRecordType<TLAsset>('asset', {\n\tscope: 'document',\n}).withDefaultProperties(() => ({\n\tmeta: {},\n}))\n\n/**\n * Branded string type for asset record identifiers.\n * Prevents mixing asset IDs with other record IDs at compile time.\n *\n * @example\n * ```ts\n * const imageShape = {\n * type: 'image',\n * props: {\n * assetId: 'asset:image123' as TLAssetId,\n * },\n * }\n * ```\n *\n * @public\n */\nexport type TLAssetId = RecordId<TLBaseAsset<any, any>>\n\n/**\n * Union type of all shapes that reference assets through an assetId property.\n * Includes image shapes, video shapes, and any other shapes that depend on external assets.\n *\n * @example\n * ```ts\n * function handleAssetShape(shape: TLAssetShape) {\n * const assetId = shape.props.assetId\n * if (!assetId) return\n * const asset = editor.getAsset(assetId)\n * // Handle the asset...\n * }\n * ```\n *\n * @public\n */\nexport type TLAssetShape = ExtractShapeByProps<{ assetId: TLAssetId }>\n\n/**\n * Creates a migration sequence for asset properties.\n *\n * @example\n * ```ts\n * const migrations = createAssetPropsMigrationSequence({\n * sequence: [\n * { id: 'com.myapp.asset.custom/1', up: (props) => { props.newField = '' } },\n * ],\n * })\n * ```\n *\n * @public\n */\nexport function createAssetPropsMigrationSequence(\n\tmigrations: TLPropsMigrations\n): TLPropsMigrations {\n\treturn migrations\n}\n\n/**\n * Creates properly formatted migration IDs for asset properties.\n *\n * @example\n * ```ts\n * const assetPropsVersions = createAssetPropsMigrationIds('file', {\n * AddFoo: 1,\n * RenameBar: 2,\n * })\n * // => { AddFoo: 'com.tldraw.asset.file/1', RenameBar: 'com.tldraw.asset.file/2' }\n * ```\n *\n * @public\n */\nexport function createAssetPropsMigrationIds<S extends string, T extends Record<string, number>>(\n\tassetType: S,\n\tids: T\n): { [k in keyof T]: `com.tldraw.asset.${S}/${T[k]}` } {\n\treturn mapObjectMapValues(ids, (_k, v) => `com.tldraw.asset.${assetType}/${v}`) as any\n}\n"],
"mappings": "AAAA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OAEM;AACP,SAAS,0BAA0B;AACnC,SAAS,SAAS;AAClB,SAAS,4BAAyC;AAkG3C,MAAM,gBAAgB,mBAAmB,oBAAoB;AAAA,EACnE,SAAS;AACV,CAAU;AAiBH,MAAM,kBAAkB,8BAA8B;AAAA,EAC5D,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,IACT;AAAA,MACC,IAAI,cAAc;AAAA,MAClB,IAAI,CAAC,WAAW;AACf;AAAC,QAAC,OAAe,OAAO,CAAC;AAAA,MAC1B;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAkDM,SAAS,sBAAsB,QAAyC;AAC9E,SAAO,iBAAiB,SAAS;AAAA,IAChC,OAAO;AAAA,IACP,WAAW,EAAE;AAAA,MACZ;AAAA,MACA,EAAE;AAAA,QACD;AAAA,QACA;AAAA,UAAmB;AAAA,UAAQ,CAAC,MAAM,EAAE,OAAO,KAAK,MAC/C,qBAAqB,MAAM,OAAO,IAAI;AAAA,QACvC;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC,EAAE,sBAAsB,OAAO;AAAA,IAC/B,MAAM,CAAC;AAAA,EACR,EAAE;AACH;AAOO,MAAM,kBAAkB,iBAA0B,SAAS;AAAA,EACjE,OAAO;AACR,CAAC,EAAE,sBAAsB,OAAO;AAAA,EAC/B,MAAM,CAAC;AACR,EAAE;AAoDK,SAAS,kCACf,YACoB;AACpB,SAAO;AACR;AAgBO,SAAS,6BACf,WACA,KACsD;AACtD,SAAO,mBAAmB,KAAK,CAAC,IAAI,MAAM,oBAAoB,SAAS,IAAI,CAAC,EAAE;AAC/E;",
"names": []
}