fd29006538
This PR adds a `meta` property to shapes and other records. It adds it to: - asset - camera - document - instance - instancePageState - instancePresence - page - pointer - rootShape ## Setting meta This data can generally be added wherever you would normally update the corresponding record. An exception exists for shapes, which can be updated using a partial of the `meta` in the same way that we update shapes with a partial of `props`. ```ts this.updateShapes([{ id: myShape.id, type: "geo", meta: { nemesis: "steve", special: true } ]) ``` ## `Editor.getInitialMetaForShape` The `Editor.getInitialMetaForShape` method is kind of a hack to set the initial meta property for newly created shapes. You can set it externally. Escape hatch! ### Change Type - [x] `minor` — New feature ### Test Plan todo - [ ] Unit Tests (todo) ### Release Notes - todo
65 lines
2.3 KiB
TypeScript
65 lines
2.3 KiB
TypeScript
import { Migrations, StoreSchema } from '@tldraw/store'
|
|
import { objectMapValues } from '@tldraw/utils'
|
|
import { TLStoreProps, createIntegrityChecker, onValidationFailure } from './TLStore'
|
|
import { AssetRecordType } from './records/TLAsset'
|
|
import { CameraRecordType } from './records/TLCamera'
|
|
import { DocumentRecordType } from './records/TLDocument'
|
|
import { createInstanceRecordType } from './records/TLInstance'
|
|
import { PageRecordType } from './records/TLPage'
|
|
import { InstancePageStateRecordType } from './records/TLPageState'
|
|
import { PointerRecordType } from './records/TLPointer'
|
|
import { InstancePresenceRecordType } from './records/TLPresence'
|
|
import { TLRecord } from './records/TLRecord'
|
|
import { createShapeRecordType, getShapePropKeysByStyle } from './records/TLShape'
|
|
import { storeMigrations } from './store-migrations'
|
|
import { StyleProp } from './styles/StyleProp'
|
|
|
|
/** @public */
|
|
export type SchemaShapeInfo = {
|
|
migrations?: Migrations
|
|
props?: Record<string, { validate: (prop: any) => any }>
|
|
meta?: Record<string, { validate: (prop: any) => any }>
|
|
}
|
|
|
|
/** @public */
|
|
export type TLSchema = StoreSchema<TLRecord, TLStoreProps>
|
|
|
|
/**
|
|
* Create a TLSchema with custom shapes. Custom shapes cannot override default shapes.
|
|
*
|
|
* @param opts - Options
|
|
*
|
|
* @public */
|
|
export function createTLSchema({ shapes }: { shapes: Record<string, SchemaShapeInfo> }): TLSchema {
|
|
const stylesById = new Map<string, StyleProp<unknown>>()
|
|
for (const shape of objectMapValues(shapes)) {
|
|
for (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) {
|
|
if (stylesById.has(style.id) && stylesById.get(style.id) !== style) {
|
|
throw new Error(`Multiple StyleProp instances with the same id: ${style.id}`)
|
|
}
|
|
stylesById.set(style.id, style)
|
|
}
|
|
}
|
|
|
|
const ShapeRecordType = createShapeRecordType(shapes)
|
|
const InstanceRecordType = createInstanceRecordType(stylesById)
|
|
|
|
return StoreSchema.create(
|
|
{
|
|
asset: AssetRecordType,
|
|
camera: CameraRecordType,
|
|
document: DocumentRecordType,
|
|
instance: InstanceRecordType,
|
|
instance_page_state: InstancePageStateRecordType,
|
|
page: PageRecordType,
|
|
shape: ShapeRecordType,
|
|
instance_presence: InstancePresenceRecordType,
|
|
pointer: PointerRecordType,
|
|
},
|
|
{
|
|
snapshotMigrations: storeMigrations,
|
|
onValidationFailure,
|
|
createIntegrityChecker: createIntegrityChecker,
|
|
}
|
|
)
|
|
}
|