({
shapes = defaultShapeSchemas,
bindings = defaultBindingSchemas,
assets = defaultAssetSchemas,
user,
records = {},
migrations,
}: {
shapes?: Record<string, SchemaPropsInfo>
bindings?: Record<string, SchemaPropsInfo>
assets?: Record<string, SchemaPropsInfo>
user?: UserSchemaInfo
records?: Record<string, CustomRecordInfo>
migrations?: readonly MigrationSequence[]
} = {})
| 337 | * ``` |
| 338 | */ |
| 339 | export function createTLSchema({ |
| 340 | shapes = defaultShapeSchemas, |
| 341 | bindings = defaultBindingSchemas, |
| 342 | assets = defaultAssetSchemas, |
| 343 | user, |
| 344 | records = {}, |
| 345 | migrations, |
| 346 | }: { |
| 347 | shapes?: Record<string, SchemaPropsInfo> |
| 348 | bindings?: Record<string, SchemaPropsInfo> |
| 349 | assets?: Record<string, SchemaPropsInfo> |
| 350 | user?: UserSchemaInfo |
| 351 | records?: Record<string, CustomRecordInfo> |
| 352 | migrations?: readonly MigrationSequence[] |
| 353 | } = {}): TLSchema { |
| 354 | const stylesById = new Map<string, StyleProp<unknown>>() |
| 355 | for (const shape of objectMapValues(shapes)) { |
| 356 | for (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) { |
| 357 | if (stylesById.has(style.id) && stylesById.get(style.id) !== style) { |
| 358 | throw new Error(`Multiple StyleProp instances with the same id: ${style.id}`) |
| 359 | } |
| 360 | stylesById.set(style.id, style) |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | const ShapeRecordType = createShapeRecordType(shapes) |
| 365 | const BindingRecordType = createBindingRecordType(bindings) |
| 366 | const _AssetRecordType = createAssetRecordType(assets) |
| 367 | const InstanceRecordType = createInstanceRecordType(stylesById) |
| 368 | const CustomUserRecordType = user ? createUserRecordType(user) : UserRecordType |
| 369 | |
| 370 | // Create RecordTypes for custom records |
| 371 | const builtInTypeNames = new Set([ |
| 372 | 'asset', |
| 373 | 'binding', |
| 374 | 'camera', |
| 375 | 'document', |
| 376 | 'instance', |
| 377 | 'instance_page_state', |
| 378 | 'page', |
| 379 | 'instance_presence', |
| 380 | 'pointer', |
| 381 | 'shape', |
| 382 | 'store', |
| 383 | 'user', |
| 384 | ]) |
| 385 | const customRecordTypes: Record<string, { createId: any }> = {} |
| 386 | for (const [typeName, config] of Object.entries(records)) { |
| 387 | if (builtInTypeNames.has(typeName)) { |
| 388 | throw new Error( |
| 389 | `Custom record type name '${typeName}' conflicts with tldraw's built-in record type of that name. Choose a different name instead.` |
| 390 | ) |
| 391 | } |
| 392 | customRecordTypes[typeName] = createCustomRecordType(typeName, config) |
| 393 | } |
| 394 | |
| 395 | return StoreSchema.create( |
| 396 | { |
searching dependent graphs…