@tldraw/tlschema 4.1.0-next.b6dfe9bccde9 → 4.1.0-next.cb6f90590225

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/dist-cjs/TLStore.js +3 -10
  2. package/dist-cjs/TLStore.js.map +2 -2
  3. package/dist-cjs/assets/TLBaseAsset.js.map +2 -2
  4. package/dist-cjs/assets/TLBookmarkAsset.js.map +2 -2
  5. package/dist-cjs/assets/TLImageAsset.js.map +2 -2
  6. package/dist-cjs/assets/TLVideoAsset.js.map +2 -2
  7. package/dist-cjs/bindings/TLArrowBinding.js.map +2 -2
  8. package/dist-cjs/bindings/TLBaseBinding.js.map +2 -2
  9. package/dist-cjs/createPresenceStateDerivation.js.map +2 -2
  10. package/dist-cjs/createTLSchema.js.map +2 -2
  11. package/dist-cjs/index.d.ts +4416 -223
  12. package/dist-cjs/index.js +1 -1
  13. package/dist-cjs/index.js.map +2 -2
  14. package/dist-cjs/misc/TLColor.js.map +2 -2
  15. package/dist-cjs/misc/TLCursor.js.map +2 -2
  16. package/dist-cjs/misc/TLHandle.js.map +2 -2
  17. package/dist-cjs/misc/TLOpacity.js.map +2 -2
  18. package/dist-cjs/misc/TLRichText.js.map +2 -2
  19. package/dist-cjs/misc/TLScribble.js.map +2 -2
  20. package/dist-cjs/misc/geometry-types.js.map +2 -2
  21. package/dist-cjs/misc/id-validator.js.map +2 -2
  22. package/dist-cjs/records/TLAsset.js.map +2 -2
  23. package/dist-cjs/records/TLBinding.js.map +2 -2
  24. package/dist-cjs/records/TLCamera.js.map +2 -2
  25. package/dist-cjs/records/TLDocument.js.map +2 -2
  26. package/dist-cjs/records/TLInstance.js.map +2 -2
  27. package/dist-cjs/records/TLPage.js.map +2 -2
  28. package/dist-cjs/records/TLPageState.js.map +2 -2
  29. package/dist-cjs/records/TLPointer.js.map +2 -2
  30. package/dist-cjs/records/TLPresence.js.map +2 -2
  31. package/dist-cjs/records/TLRecord.js.map +1 -1
  32. package/dist-cjs/records/TLShape.js.map +2 -2
  33. package/dist-cjs/recordsWithProps.js.map +2 -2
  34. package/dist-cjs/shapes/ShapeWithCrop.js.map +1 -1
  35. package/dist-cjs/shapes/TLArrowShape.js.map +2 -2
  36. package/dist-cjs/shapes/TLBaseShape.js.map +2 -2
  37. package/dist-cjs/shapes/TLBookmarkShape.js.map +2 -2
  38. package/dist-cjs/shapes/TLDrawShape.js.map +2 -2
  39. package/dist-cjs/shapes/TLEmbedShape.js.map +2 -2
  40. package/dist-cjs/shapes/TLFrameShape.js.map +2 -2
  41. package/dist-cjs/shapes/TLGeoShape.js.map +2 -2
  42. package/dist-cjs/shapes/TLGroupShape.js.map +2 -2
  43. package/dist-cjs/shapes/TLHighlightShape.js.map +2 -2
  44. package/dist-cjs/shapes/TLImageShape.js.map +2 -2
  45. package/dist-cjs/shapes/TLLineShape.js.map +2 -2
  46. package/dist-cjs/shapes/TLNoteShape.js.map +2 -2
  47. package/dist-cjs/shapes/TLTextShape.js.map +2 -2
  48. package/dist-cjs/shapes/TLVideoShape.js.map +2 -2
  49. package/dist-cjs/store-migrations.js.map +2 -2
  50. package/dist-cjs/styles/TLColorStyle.js.map +2 -2
  51. package/dist-cjs/styles/TLDashStyle.js.map +2 -2
  52. package/dist-cjs/styles/TLFillStyle.js.map +2 -2
  53. package/dist-cjs/styles/TLFontStyle.js.map +2 -2
  54. package/dist-cjs/styles/TLHorizontalAlignStyle.js.map +2 -2
  55. package/dist-cjs/styles/TLSizeStyle.js.map +2 -2
  56. package/dist-cjs/styles/TLTextAlignStyle.js.map +2 -2
  57. package/dist-cjs/styles/TLVerticalAlignStyle.js.map +2 -2
  58. package/dist-cjs/translations/translations.js +1 -1
  59. package/dist-cjs/translations/translations.js.map +2 -2
  60. package/dist-cjs/util-types.js.map +1 -1
  61. package/dist-esm/TLStore.mjs +3 -10
  62. package/dist-esm/TLStore.mjs.map +2 -2
  63. package/dist-esm/assets/TLBaseAsset.mjs.map +2 -2
  64. package/dist-esm/assets/TLBookmarkAsset.mjs.map +2 -2
  65. package/dist-esm/assets/TLImageAsset.mjs.map +2 -2
  66. package/dist-esm/assets/TLVideoAsset.mjs.map +2 -2
  67. package/dist-esm/bindings/TLArrowBinding.mjs.map +2 -2
  68. package/dist-esm/bindings/TLBaseBinding.mjs.map +2 -2
  69. package/dist-esm/createPresenceStateDerivation.mjs.map +2 -2
  70. package/dist-esm/createTLSchema.mjs.map +2 -2
  71. package/dist-esm/index.d.mts +4416 -223
  72. package/dist-esm/index.mjs +1 -1
  73. package/dist-esm/index.mjs.map +2 -2
  74. package/dist-esm/misc/TLColor.mjs.map +2 -2
  75. package/dist-esm/misc/TLCursor.mjs.map +2 -2
  76. package/dist-esm/misc/TLHandle.mjs.map +2 -2
  77. package/dist-esm/misc/TLOpacity.mjs.map +2 -2
  78. package/dist-esm/misc/TLRichText.mjs.map +2 -2
  79. package/dist-esm/misc/TLScribble.mjs.map +2 -2
  80. package/dist-esm/misc/geometry-types.mjs.map +2 -2
  81. package/dist-esm/misc/id-validator.mjs.map +2 -2
  82. package/dist-esm/records/TLAsset.mjs.map +2 -2
  83. package/dist-esm/records/TLBinding.mjs.map +2 -2
  84. package/dist-esm/records/TLCamera.mjs.map +2 -2
  85. package/dist-esm/records/TLDocument.mjs.map +2 -2
  86. package/dist-esm/records/TLInstance.mjs.map +2 -2
  87. package/dist-esm/records/TLPage.mjs.map +2 -2
  88. package/dist-esm/records/TLPageState.mjs.map +2 -2
  89. package/dist-esm/records/TLPointer.mjs.map +2 -2
  90. package/dist-esm/records/TLPresence.mjs.map +2 -2
  91. package/dist-esm/records/TLShape.mjs.map +2 -2
  92. package/dist-esm/recordsWithProps.mjs.map +2 -2
  93. package/dist-esm/shapes/TLArrowShape.mjs.map +2 -2
  94. package/dist-esm/shapes/TLBaseShape.mjs.map +2 -2
  95. package/dist-esm/shapes/TLBookmarkShape.mjs.map +2 -2
  96. package/dist-esm/shapes/TLDrawShape.mjs.map +2 -2
  97. package/dist-esm/shapes/TLEmbedShape.mjs.map +2 -2
  98. package/dist-esm/shapes/TLFrameShape.mjs.map +2 -2
  99. package/dist-esm/shapes/TLGeoShape.mjs.map +2 -2
  100. package/dist-esm/shapes/TLGroupShape.mjs.map +2 -2
  101. package/dist-esm/shapes/TLHighlightShape.mjs.map +2 -2
  102. package/dist-esm/shapes/TLImageShape.mjs.map +2 -2
  103. package/dist-esm/shapes/TLLineShape.mjs.map +2 -2
  104. package/dist-esm/shapes/TLNoteShape.mjs.map +2 -2
  105. package/dist-esm/shapes/TLTextShape.mjs.map +2 -2
  106. package/dist-esm/shapes/TLVideoShape.mjs.map +2 -2
  107. package/dist-esm/store-migrations.mjs.map +2 -2
  108. package/dist-esm/styles/TLColorStyle.mjs.map +2 -2
  109. package/dist-esm/styles/TLDashStyle.mjs.map +2 -2
  110. package/dist-esm/styles/TLFillStyle.mjs.map +2 -2
  111. package/dist-esm/styles/TLFontStyle.mjs.map +2 -2
  112. package/dist-esm/styles/TLHorizontalAlignStyle.mjs.map +2 -2
  113. package/dist-esm/styles/TLSizeStyle.mjs.map +2 -2
  114. package/dist-esm/styles/TLTextAlignStyle.mjs.map +2 -2
  115. package/dist-esm/styles/TLVerticalAlignStyle.mjs.map +2 -2
  116. package/dist-esm/translations/translations.mjs +1 -1
  117. package/dist-esm/translations/translations.mjs.map +2 -2
  118. package/package.json +5 -5
  119. package/src/TLStore.test.ts +644 -0
  120. package/src/TLStore.ts +205 -20
  121. package/src/assets/TLBaseAsset.ts +90 -7
  122. package/src/assets/TLBookmarkAsset.test.ts +96 -0
  123. package/src/assets/TLBookmarkAsset.ts +52 -2
  124. package/src/assets/TLImageAsset.test.ts +213 -0
  125. package/src/assets/TLImageAsset.ts +60 -2
  126. package/src/assets/TLVideoAsset.test.ts +105 -0
  127. package/src/assets/TLVideoAsset.ts +93 -4
  128. package/src/bindings/TLArrowBinding.test.ts +55 -0
  129. package/src/bindings/TLArrowBinding.ts +132 -10
  130. package/src/bindings/TLBaseBinding.ts +140 -3
  131. package/src/createPresenceStateDerivation.test.ts +158 -0
  132. package/src/createPresenceStateDerivation.ts +71 -2
  133. package/src/createTLSchema.test.ts +181 -0
  134. package/src/createTLSchema.ts +164 -7
  135. package/src/index.ts +32 -0
  136. package/src/misc/TLColor.ts +50 -6
  137. package/src/misc/TLCursor.ts +110 -8
  138. package/src/misc/TLHandle.ts +86 -6
  139. package/src/misc/TLOpacity.ts +51 -2
  140. package/src/misc/TLRichText.ts +56 -3
  141. package/src/misc/TLScribble.ts +105 -5
  142. package/src/misc/geometry-types.ts +30 -2
  143. package/src/misc/id-validator.test.ts +50 -0
  144. package/src/misc/id-validator.ts +20 -1
  145. package/src/records/TLAsset.test.ts +234 -0
  146. package/src/records/TLAsset.ts +165 -8
  147. package/src/records/TLBinding.test.ts +22 -0
  148. package/src/records/TLBinding.ts +277 -11
  149. package/src/records/TLCamera.test.ts +19 -0
  150. package/src/records/TLCamera.ts +118 -7
  151. package/src/records/TLDocument.test.ts +35 -0
  152. package/src/records/TLDocument.ts +148 -8
  153. package/src/records/TLInstance.test.ts +201 -0
  154. package/src/records/TLInstance.ts +117 -9
  155. package/src/records/TLPage.test.ts +110 -0
  156. package/src/records/TLPage.ts +106 -8
  157. package/src/records/TLPageState.test.ts +228 -0
  158. package/src/records/TLPageState.ts +88 -7
  159. package/src/records/TLPointer.test.ts +63 -0
  160. package/src/records/TLPointer.ts +105 -7
  161. package/src/records/TLPresence.test.ts +190 -0
  162. package/src/records/TLPresence.ts +99 -5
  163. package/src/records/TLRecord.test.ts +70 -0
  164. package/src/records/TLRecord.ts +43 -1
  165. package/src/records/TLShape.test.ts +232 -0
  166. package/src/records/TLShape.ts +289 -12
  167. package/src/recordsWithProps.test.ts +188 -0
  168. package/src/recordsWithProps.ts +131 -2
  169. package/src/shapes/ShapeWithCrop.test.ts +18 -0
  170. package/src/shapes/ShapeWithCrop.ts +64 -2
  171. package/src/shapes/TLArrowShape.test.ts +505 -0
  172. package/src/shapes/TLArrowShape.ts +188 -10
  173. package/src/shapes/TLBaseShape.test.ts +142 -0
  174. package/src/shapes/TLBaseShape.ts +103 -4
  175. package/src/shapes/TLBookmarkShape.test.ts +122 -0
  176. package/src/shapes/TLBookmarkShape.ts +58 -4
  177. package/src/shapes/TLDrawShape.test.ts +177 -0
  178. package/src/shapes/TLDrawShape.ts +97 -6
  179. package/src/shapes/TLEmbedShape.test.ts +286 -0
  180. package/src/shapes/TLEmbedShape.ts +57 -4
  181. package/src/shapes/TLFrameShape.test.ts +71 -0
  182. package/src/shapes/TLFrameShape.ts +59 -4
  183. package/src/shapes/TLGeoShape.test.ts +247 -0
  184. package/src/shapes/TLGeoShape.ts +103 -7
  185. package/src/shapes/TLGroupShape.test.ts +59 -0
  186. package/src/shapes/TLGroupShape.ts +52 -4
  187. package/src/shapes/TLHighlightShape.test.ts +325 -0
  188. package/src/shapes/TLHighlightShape.ts +79 -4
  189. package/src/shapes/TLImageShape.test.ts +534 -0
  190. package/src/shapes/TLImageShape.ts +105 -5
  191. package/src/shapes/TLLineShape.test.ts +269 -0
  192. package/src/shapes/TLLineShape.ts +128 -8
  193. package/src/shapes/TLNoteShape.test.ts +1568 -0
  194. package/src/shapes/TLNoteShape.ts +97 -4
  195. package/src/shapes/TLTextShape.test.ts +407 -0
  196. package/src/shapes/TLTextShape.ts +94 -4
  197. package/src/shapes/TLVideoShape.test.ts +112 -0
  198. package/src/shapes/TLVideoShape.ts +99 -4
  199. package/src/store-migrations.test.ts +88 -0
  200. package/src/store-migrations.ts +47 -1
  201. package/src/styles/TLColorStyle.test.ts +439 -0
  202. package/src/styles/TLColorStyle.ts +228 -10
  203. package/src/styles/TLDashStyle.ts +54 -2
  204. package/src/styles/TLFillStyle.ts +54 -2
  205. package/src/styles/TLFontStyle.ts +72 -3
  206. package/src/styles/TLHorizontalAlignStyle.ts +55 -2
  207. package/src/styles/TLSizeStyle.ts +54 -2
  208. package/src/styles/TLTextAlignStyle.ts +52 -2
  209. package/src/styles/TLVerticalAlignStyle.ts +52 -2
  210. package/src/translations/translations.test.ts +378 -35
  211. package/src/translations/translations.ts +157 -10
  212. package/src/util-types.ts +51 -1
@@ -0,0 +1,234 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { getTestMigration } from '../__tests__/migrationTestUtils'
3
+ import {
4
+ assetMigrations,
5
+ AssetRecordType,
6
+ assetValidator,
7
+ assetVersions,
8
+ TLAssetId,
9
+ } from './TLAsset'
10
+
11
+ describe('TLAsset', () => {
12
+ describe('assetValidator', () => {
13
+ it('should validate different asset types using discriminated union', () => {
14
+ const imageAsset = {
15
+ id: 'asset:test_image',
16
+ typeName: 'asset' as const,
17
+ type: 'image' as const,
18
+ props: {
19
+ w: 100,
20
+ h: 100,
21
+ name: 'test.jpg',
22
+ isAnimated: false,
23
+ mimeType: 'image/jpeg',
24
+ src: 'https://example.com/test.jpg',
25
+ },
26
+ meta: {},
27
+ }
28
+
29
+ const videoAsset = {
30
+ id: 'asset:test_video',
31
+ typeName: 'asset' as const,
32
+ type: 'video' as const,
33
+ props: {
34
+ w: 640,
35
+ h: 480,
36
+ name: 'test.mp4',
37
+ isAnimated: true,
38
+ mimeType: 'video/mp4',
39
+ src: 'https://example.com/test.mp4',
40
+ },
41
+ meta: {},
42
+ }
43
+
44
+ const bookmarkAsset = {
45
+ id: 'asset:test_bookmark',
46
+ typeName: 'asset' as const,
47
+ type: 'bookmark' as const,
48
+ props: {
49
+ title: 'Test Site',
50
+ description: 'A test bookmark',
51
+ image: 'https://example.com/image.png',
52
+ favicon: 'https://example.com/favicon.ico',
53
+ src: 'https://example.com',
54
+ },
55
+ meta: {},
56
+ }
57
+
58
+ expect(() => assetValidator.validate(imageAsset)).not.toThrow()
59
+ expect(() => assetValidator.validate(videoAsset)).not.toThrow()
60
+ expect(() => assetValidator.validate(bookmarkAsset)).not.toThrow()
61
+
62
+ expect(assetValidator.validate(imageAsset).type).toBe('image')
63
+ expect(assetValidator.validate(videoAsset).type).toBe('video')
64
+ expect(assetValidator.validate(bookmarkAsset).type).toBe('bookmark')
65
+ })
66
+
67
+ it('should reject invalid asset types', () => {
68
+ const invalidAsset = {
69
+ id: 'asset:invalid',
70
+ typeName: 'asset' as const,
71
+ type: 'invalid_type' as any,
72
+ props: {
73
+ w: 100,
74
+ h: 100,
75
+ name: 'test.jpg',
76
+ },
77
+ meta: {},
78
+ }
79
+
80
+ expect(() => assetValidator.validate(invalidAsset)).toThrow()
81
+ })
82
+
83
+ it('should require valid asset structure', () => {
84
+ // Wrong typeName
85
+ const wrongTypeName = {
86
+ id: 'asset:wrong_typename',
87
+ typeName: 'shape' as const,
88
+ type: 'image' as const,
89
+ props: {
90
+ w: 100,
91
+ h: 100,
92
+ name: 'test.jpg',
93
+ isAnimated: false,
94
+ mimeType: 'image/jpeg',
95
+ src: 'https://example.com/test.jpg',
96
+ },
97
+ meta: {},
98
+ }
99
+ expect(() => assetValidator.validate(wrongTypeName)).toThrow()
100
+
101
+ // Missing meta
102
+ const noMeta = {
103
+ id: 'asset:no_meta',
104
+ typeName: 'asset' as const,
105
+ type: 'image' as const,
106
+ props: {
107
+ w: 100,
108
+ h: 100,
109
+ name: 'test.jpg',
110
+ isAnimated: false,
111
+ mimeType: 'image/jpeg',
112
+ src: 'https://example.com/test.jpg',
113
+ },
114
+ }
115
+ expect(() => assetValidator.validate(noMeta)).toThrow()
116
+
117
+ // Wrong ID prefix
118
+ const wrongId = {
119
+ id: 'shape:wrong_prefix',
120
+ typeName: 'asset' as const,
121
+ type: 'image' as const,
122
+ props: {
123
+ w: 100,
124
+ h: 100,
125
+ name: 'test.jpg',
126
+ isAnimated: false,
127
+ mimeType: 'image/jpeg',
128
+ src: 'https://example.com/test.jpg',
129
+ },
130
+ meta: {},
131
+ }
132
+ expect(() => assetValidator.validate(wrongId)).toThrow()
133
+ })
134
+ })
135
+
136
+ describe('assetMigrations', () => {
137
+ it('should have correct migration structure', () => {
138
+ expect(assetMigrations.sequenceId).toBe('com.tldraw.asset')
139
+ expect(assetMigrations.sequence).toHaveLength(1)
140
+ expect(assetMigrations.sequence[0].id).toBe(assetVersions.AddMeta)
141
+ })
142
+ })
143
+
144
+ describe('AddMeta migration', () => {
145
+ const { up } = getTestMigration(assetVersions.AddMeta)
146
+
147
+ it('should add empty meta property', () => {
148
+ const assetWithoutMeta = {
149
+ id: 'asset:test',
150
+ typeName: 'asset',
151
+ type: 'image',
152
+ props: {
153
+ w: 100,
154
+ h: 100,
155
+ name: 'test.jpg',
156
+ isAnimated: false,
157
+ mimeType: 'image/jpeg',
158
+ src: 'https://example.com/test.jpg',
159
+ },
160
+ }
161
+
162
+ const result = up(assetWithoutMeta)
163
+ expect(result.meta).toEqual({})
164
+ expect(result.props).toEqual(assetWithoutMeta.props)
165
+ })
166
+
167
+ it('should overwrite existing meta property', () => {
168
+ const assetWithMeta = {
169
+ id: 'asset:test',
170
+ typeName: 'asset',
171
+ type: 'image',
172
+ props: {
173
+ w: 100,
174
+ h: 100,
175
+ name: 'test.jpg',
176
+ isAnimated: false,
177
+ mimeType: 'image/jpeg',
178
+ src: 'https://example.com/test.jpg',
179
+ },
180
+ meta: { existing: 'data' },
181
+ }
182
+
183
+ const result = up(assetWithMeta)
184
+ expect(result.meta).toEqual({}) // Migration always sets to empty object
185
+ })
186
+
187
+ it('should preserve other properties during migration', () => {
188
+ const assetWithExtraProps = {
189
+ id: 'asset:extra_props',
190
+ typeName: 'asset',
191
+ type: 'image',
192
+ props: {
193
+ w: 200,
194
+ h: 150,
195
+ name: 'extra.png',
196
+ isAnimated: false,
197
+ mimeType: 'image/png',
198
+ src: 'https://example.com/extra.png',
199
+ },
200
+ customProperty: 'should be preserved',
201
+ }
202
+
203
+ const result = up(assetWithExtraProps)
204
+ expect(result.meta).toEqual({})
205
+ expect(result.customProperty).toBe('should be preserved')
206
+ })
207
+ })
208
+
209
+ describe('AssetRecordType', () => {
210
+ it('should have correct configuration', () => {
211
+ expect(AssetRecordType.typeName).toBe('asset')
212
+ expect(AssetRecordType.scope).toBe('document')
213
+ expect(AssetRecordType.validator).toBe(assetValidator)
214
+ })
215
+
216
+ it('should create records with default meta property', () => {
217
+ const assetRecord = AssetRecordType.create({
218
+ id: 'asset:test' as TLAssetId,
219
+ type: 'image',
220
+ props: {
221
+ w: 100,
222
+ h: 100,
223
+ name: 'test.jpg',
224
+ isAnimated: false,
225
+ mimeType: 'image/jpeg',
226
+ src: 'https://example.com/test.jpg',
227
+ },
228
+ })
229
+
230
+ expect(assetRecord.meta).toEqual({})
231
+ expect(assetRecord.typeName).toBe('asset')
232
+ })
233
+ })
234
+ })
@@ -11,10 +11,48 @@ import { imageAssetValidator, TLImageAsset } from '../assets/TLImageAsset'
11
11
  import { TLVideoAsset, videoAssetValidator } from '../assets/TLVideoAsset'
12
12
  import { TLShape } from './TLShape'
13
13
 
14
- /** @public */
14
+ /**
15
+ * Union type representing all possible asset types in tldraw.
16
+ * Assets represent external resources like images, videos, or bookmarks that can be referenced by shapes.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const imageAsset: TLAsset = {
21
+ * id: 'asset:image123',
22
+ * typeName: 'asset',
23
+ * type: 'image',
24
+ * props: {
25
+ * src: 'https://example.com/image.jpg',
26
+ * w: 800,
27
+ * h: 600,
28
+ * mimeType: 'image/jpeg',
29
+ * isAnimated: false
30
+ * },
31
+ * meta: {}
32
+ * }
33
+ * ```
34
+ *
35
+ * @public
36
+ */
15
37
  export type TLAsset = TLImageAsset | TLVideoAsset | TLBookmarkAsset
16
38
 
17
- /** @public */
39
+ /**
40
+ * Validator for TLAsset records that ensures runtime type safety.
41
+ * Uses a discriminated union based on the 'type' field to validate different asset types.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * // Validation happens automatically when assets are stored
46
+ * try {
47
+ * const validatedAsset = assetValidator.validate(assetData)
48
+ * store.put([validatedAsset])
49
+ * } catch (error) {
50
+ * console.error('Asset validation failed:', error.message)
51
+ * }
52
+ * ```
53
+ *
54
+ * @public
55
+ */
18
56
  export const assetValidator: T.Validator<TLAsset> = T.model(
19
57
  'asset',
20
58
  T.union('type', {
@@ -24,12 +62,37 @@ export const assetValidator: T.Validator<TLAsset> = T.model(
24
62
  })
25
63
  )
26
64
 
27
- /** @public */
65
+ /**
66
+ * Migration version identifiers for asset record schema evolution.
67
+ * Each version represents a breaking change that requires data migration.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * // Check if a migration is needed
72
+ * const needsMigration = currentVersion < assetVersions.AddMeta
73
+ * ```
74
+ *
75
+ * @public
76
+ */
28
77
  export const assetVersions = createMigrationIds('com.tldraw.asset', {
29
78
  AddMeta: 1,
30
79
  } as const)
31
80
 
32
- /** @public */
81
+ /**
82
+ * Migration sequence for evolving asset record structure over time.
83
+ * Handles converting asset records from older schema versions to current format.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * // Migration is applied automatically when loading old documents
88
+ * const migratedStore = migrator.migrateStoreSnapshot({
89
+ * schema: oldSchema,
90
+ * store: oldStoreSnapshot
91
+ * })
92
+ * ```
93
+ *
94
+ * @public
95
+ */
33
96
  export const assetMigrations = createRecordMigrationSequence({
34
97
  sequenceId: 'com.tldraw.asset',
35
98
  recordType: 'asset',
@@ -43,7 +106,27 @@ export const assetMigrations = createRecordMigrationSequence({
43
106
  ],
44
107
  })
45
108
 
46
- /** @public */
109
+ /**
110
+ * Partial type for TLAsset allowing optional properties except id and type.
111
+ * Useful for creating or updating assets where not all properties need to be specified.
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * // Create a partial asset for updating
116
+ * const partialAsset: TLAssetPartial<TLImageAsset> = {
117
+ * id: 'asset:image123',
118
+ * type: 'image',
119
+ * props: {
120
+ * w: 800 // Only updating width
121
+ * }
122
+ * }
123
+ *
124
+ * // Use in asset updates
125
+ * editor.updateAssets([partialAsset])
126
+ * ```
127
+ *
128
+ * @public
129
+ */
47
130
  export type TLAssetPartial<T extends TLAsset = TLAsset> = T extends T
48
131
  ? {
49
132
  id: TLAssetId
@@ -53,7 +136,31 @@ export type TLAssetPartial<T extends TLAsset = TLAsset> = T extends T
53
136
  } & Partial<Omit<T, 'type' | 'id' | 'props' | 'meta'>>
54
137
  : never
55
138
 
56
- /** @public */
139
+ /**
140
+ * Record type definition for TLAsset with validation and default properties.
141
+ * Configures assets as document-scoped records that persist across sessions.
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * // Create a new asset record
146
+ * const assetRecord = AssetRecordType.create({
147
+ * id: 'asset:image123',
148
+ * type: 'image',
149
+ * props: {
150
+ * src: 'https://example.com/image.jpg',
151
+ * w: 800,
152
+ * h: 600,
153
+ * mimeType: 'image/jpeg',
154
+ * isAnimated: false
155
+ * }
156
+ * })
157
+ *
158
+ * // Store the asset
159
+ * store.put([assetRecord])
160
+ * ```
161
+ *
162
+ * @public
163
+ */
57
164
  export const AssetRecordType = createRecordType<TLAsset>('asset', {
58
165
  validator: assetValidator,
59
166
  scope: 'document',
@@ -61,8 +168,58 @@ export const AssetRecordType = createRecordType<TLAsset>('asset', {
61
168
  meta: {},
62
169
  }))
63
170
 
64
- /** @public */
171
+ /**
172
+ * Branded string type for asset record identifiers.
173
+ * Prevents mixing asset IDs with other types of record IDs at compile time.
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * import { createAssetId } from '@tldraw/tlschema'
178
+ *
179
+ * // Create a new asset ID
180
+ * const assetId: TLAssetId = createAssetId()
181
+ *
182
+ * // Use in asset records
183
+ * const asset: TLAsset = {
184
+ * id: assetId,
185
+ * // ... other properties
186
+ * }
187
+ *
188
+ * // Reference in shapes
189
+ * const imageShape: TLImageShape = {
190
+ * props: {
191
+ * assetId: assetId,
192
+ * // ... other properties
193
+ * }
194
+ * }
195
+ * ```
196
+ *
197
+ * @public
198
+ */
65
199
  export type TLAssetId = RecordId<TLBaseAsset<any, any>>
66
200
 
67
- /** @public */
201
+ /**
202
+ * Union type of all shapes that reference assets through an assetId property.
203
+ * Includes image shapes, video shapes, and any other shapes that depend on external assets.
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * // Function that works with any asset-based shape
208
+ * function handleAssetShape(shape: TLAssetShape) {
209
+ * const assetId = shape.props.assetId
210
+ * if (assetId) {
211
+ * const asset = editor.getAsset(assetId)
212
+ * // Handle the asset...
213
+ * }
214
+ * }
215
+ *
216
+ * // Use with image or video shapes
217
+ * const imageShape: TLImageShape = { props: { assetId: 'asset:img1' } }
218
+ * const videoShape: TLVideoShape = { props: { assetId: 'asset:vid1' } }
219
+ * handleAssetShape(imageShape) // Works
220
+ * handleAssetShape(videoShape) // Works
221
+ * ```
222
+ *
223
+ * @public
224
+ */
68
225
  export type TLAssetShape = Extract<TLShape, { props: { assetId: TLAssetId } }>
@@ -0,0 +1,22 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { createBindingId, rootBindingMigrations } from './TLBinding'
3
+
4
+ describe('TLBinding', () => {
5
+ describe('createBindingId function', () => {
6
+ it('should generate IDs starting with binding:', () => {
7
+ const id = createBindingId()
8
+ expect(id.startsWith('binding:')).toBe(true)
9
+ })
10
+
11
+ it('should use custom ID when provided', () => {
12
+ expect(createBindingId('test')).toBe('binding:test')
13
+ })
14
+ })
15
+
16
+ describe('rootBindingMigrations', () => {
17
+ it('should have correct structure', () => {
18
+ expect(rootBindingMigrations.sequenceId).toBe('com.tldraw.binding')
19
+ expect(Array.isArray(rootBindingMigrations.sequence)).toBe(true)
20
+ })
21
+ })
22
+ })