@tldraw/tlschema 4.1.0-canary.ccd6179e1cb2 → 4.1.0-canary.e23ee15a46bc

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 +4412 -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 +4412 -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 +82 -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,112 @@
1
+ import { T } from '@tldraw/validate'
2
+ import { describe, expect, it } from 'vitest'
3
+ import { getTestMigration } from '../__tests__/migrationTestUtils'
4
+ import { TLAssetId } from '../records/TLAsset'
5
+ import { videoShapeMigrations, videoShapeProps, videoShapeVersions } from './TLVideoShape'
6
+
7
+ describe('TLVideoShape', () => {
8
+ describe('videoShapeProps validation', () => {
9
+ it('should validate dimensions as nonZeroNumber', () => {
10
+ expect(() => videoShapeProps.w.validate(1)).not.toThrow()
11
+ expect(() => videoShapeProps.h.validate(100)).not.toThrow()
12
+ expect(() => videoShapeProps.w.validate(0)).toThrow()
13
+ expect(() => videoShapeProps.h.validate(-1)).toThrow()
14
+ })
15
+
16
+ it('should validate time as number including negatives', () => {
17
+ expect(() => videoShapeProps.time.validate(0)).not.toThrow()
18
+ expect(() => videoShapeProps.time.validate(-5)).not.toThrow()
19
+ expect(() => videoShapeProps.time.validate(30.5)).not.toThrow()
20
+ expect(() => videoShapeProps.time.validate('not-number')).toThrow()
21
+ })
22
+
23
+ it('should validate boolean properties', () => {
24
+ expect(() => videoShapeProps.playing.validate(true)).not.toThrow()
25
+ expect(() => videoShapeProps.autoplay.validate(false)).not.toThrow()
26
+ expect(() => videoShapeProps.playing.validate('true')).toThrow()
27
+ })
28
+
29
+ it('should validate URLs and assetIds', () => {
30
+ expect(() => videoShapeProps.url.validate('')).not.toThrow()
31
+ expect(() => videoShapeProps.url.validate('https://example.com/video.mp4')).not.toThrow()
32
+ expect(() => videoShapeProps.assetId.validate(null)).not.toThrow()
33
+ expect(() => videoShapeProps.assetId.validate('asset:video123' as TLAssetId)).not.toThrow()
34
+ expect(() => videoShapeProps.altText.validate('Alt text')).not.toThrow()
35
+ })
36
+
37
+ it('should validate complete props object', () => {
38
+ const validator = T.object(videoShapeProps)
39
+ const validProps = {
40
+ w: 640,
41
+ h: 480,
42
+ time: 0,
43
+ playing: false,
44
+ autoplay: true,
45
+ url: 'https://example.com/video.mp4',
46
+ assetId: 'asset:video123' as TLAssetId,
47
+ altText: 'Test video',
48
+ }
49
+ expect(() => validator.validate(validProps)).not.toThrow()
50
+ })
51
+ })
52
+
53
+ describe('videoShapeVersions', () => {
54
+ it('should have expected migration versions', () => {
55
+ expect(videoShapeVersions.AddUrlProp).toBeDefined()
56
+ expect(videoShapeVersions.MakeUrlsValid).toBeDefined()
57
+ expect(videoShapeVersions.AddAltText).toBeDefined()
58
+ expect(videoShapeVersions.AddAutoplay).toBeDefined()
59
+ })
60
+ })
61
+
62
+ describe('videoShapeMigrations', () => {
63
+ it('should add url property in AddUrlProp migration', () => {
64
+ const { up } = getTestMigration(videoShapeVersions.AddUrlProp)
65
+ const oldRecord = {
66
+ props: { w: 640, h: 480, time: 30, playing: true, assetId: 'asset:video123' },
67
+ }
68
+ const result = up(oldRecord)
69
+ expect(result.props.url).toBe('')
70
+ expect(result.props.w).toBe(640)
71
+ })
72
+
73
+ it('should clear invalid URLs in MakeUrlsValid migration', () => {
74
+ const { up } = getTestMigration(videoShapeVersions.MakeUrlsValid)
75
+ const oldRecord = {
76
+ props: { url: 'invalid-url', w: 400, h: 300 },
77
+ }
78
+ const result = up(oldRecord)
79
+ expect(result.props.url).toBe('')
80
+ })
81
+
82
+ it('should add altText in AddAltText migration', () => {
83
+ const { up, down } = getTestMigration(videoShapeVersions.AddAltText)
84
+ const oldRecord = { props: { w: 800, h: 600 } }
85
+ const result = up(oldRecord)
86
+ expect(result.props.altText).toBe('')
87
+
88
+ // Test down migration removes altText
89
+ const newRecord = { props: { w: 640, h: 480, altText: 'Test' } }
90
+ const downResult = down(newRecord)
91
+ expect(downResult.props.altText).toBeUndefined()
92
+ })
93
+
94
+ it('should add autoplay in AddAutoplay migration', () => {
95
+ const { up, down } = getTestMigration(videoShapeVersions.AddAutoplay)
96
+ const oldRecord = { props: { w: 480, h: 270 } }
97
+ const result = up(oldRecord)
98
+ expect(result.props.autoplay).toBe(true)
99
+
100
+ // Test down migration removes autoplay
101
+ const newRecord = { props: { w: 800, h: 450, autoplay: false } }
102
+ const downResult = down(newRecord)
103
+ expect(downResult.props.autoplay).toBeUndefined()
104
+ })
105
+
106
+ it('should have migrations for all versions', () => {
107
+ expect(videoShapeMigrations.sequence).toBeDefined()
108
+ expect(Array.isArray(videoShapeMigrations.sequence)).toBe(true)
109
+ expect(videoShapeMigrations.sequence.length).toBeGreaterThanOrEqual(4)
110
+ })
111
+ })
112
+ })
@@ -5,7 +5,26 @@ import { createShapePropsMigrationIds, createShapePropsMigrationSequence } from
5
5
  import { RecordProps } from '../recordsWithProps'
6
6
  import { TLBaseShape } from './TLBaseShape'
7
7
 
8
- /** @public */
8
+ /**
9
+ * Configuration interface defining properties for video shapes in tldraw.
10
+ * Video shapes can display video content from URLs or asset references,
11
+ * with controls for playback state, timing, and accessibility.
12
+ *
13
+ * @public
14
+ * @example
15
+ * ```ts
16
+ * const videoProps: TLVideoShapeProps = {
17
+ * w: 640,
18
+ * h: 480,
19
+ * time: 0,
20
+ * playing: false,
21
+ * autoplay: true,
22
+ * url: 'https://example.com/video.mp4',
23
+ * assetId: 'asset:video123',
24
+ * altText: 'Educational video about shapes'
25
+ * }
26
+ * ```
27
+ */
9
28
  export interface TLVideoShapeProps {
10
29
  w: number
11
30
  h: number
@@ -17,10 +36,60 @@ export interface TLVideoShapeProps {
17
36
  altText: string
18
37
  }
19
38
 
20
- /** @public */
39
+ /**
40
+ * A video shape that can display video content with playback controls and timing.
41
+ * Video shapes support both direct URL references and asset-based video storage,
42
+ * with accessibility features and playback state management.
43
+ *
44
+ * @public
45
+ * @example
46
+ * ```ts
47
+ * const videoShape: TLVideoShape = {
48
+ * id: 'shape:video123',
49
+ * typeName: 'shape',
50
+ * type: 'video',
51
+ * x: 100,
52
+ * y: 100,
53
+ * rotation: 0,
54
+ * index: 'a1',
55
+ * parentId: 'page:main',
56
+ * isLocked: false,
57
+ * opacity: 1,
58
+ * props: {
59
+ * w: 640,
60
+ * h: 480,
61
+ * time: 15.5,
62
+ * playing: false,
63
+ * autoplay: false,
64
+ * url: 'https://example.com/video.mp4',
65
+ * assetId: 'asset:video123',
66
+ * altText: 'Product demo video'
67
+ * },
68
+ * meta: {}
69
+ * }
70
+ * ```
71
+ */
21
72
  export type TLVideoShape = TLBaseShape<'video', TLVideoShapeProps>
22
73
 
23
- /** @public */
74
+ /**
75
+ * Validation schema for video shape properties. This defines the runtime validation
76
+ * rules that ensure video shape data integrity, including URL validation, numeric
77
+ * constraints, and proper asset ID formatting.
78
+ *
79
+ * @public
80
+ * @example
81
+ * ```ts
82
+ * import { videoShapeProps } from '@tldraw/tlschema'
83
+ *
84
+ * // Validate video URL
85
+ * const isValidUrl = videoShapeProps.url.isValid('https://example.com/video.mp4')
86
+ * const isValidTime = videoShapeProps.time.isValid(42.5)
87
+ *
88
+ * if (isValidUrl && isValidTime) {
89
+ * // Video properties are valid
90
+ * }
91
+ * ```
92
+ */
24
93
  export const videoShapeProps: RecordProps<TLVideoShape> = {
25
94
  w: T.nonZeroNumber,
26
95
  h: T.nonZeroNumber,
@@ -39,9 +108,35 @@ const Versions = createShapePropsMigrationIds('video', {
39
108
  AddAutoplay: 4,
40
109
  })
41
110
 
111
+ /**
112
+ * Version identifiers for video shape migrations. These constants track
113
+ * the evolution of the video shape schema over time.
114
+ *
115
+ * @public
116
+ * @example
117
+ * ```ts
118
+ * import { videoShapeVersions } from '@tldraw/tlschema'
119
+ *
120
+ * // Check if shape data needs migration
121
+ * if (shapeVersion < videoShapeVersions.AddAltText) {
122
+ * // Apply alt text migration for accessibility
123
+ * }
124
+ * ```
125
+ */
42
126
  export { Versions as videoShapeVersions }
43
127
 
44
- /** @public */
128
+ /**
129
+ * Migration sequence for video shape schema evolution. This handles transforming
130
+ * video shape data between different versions as the schema evolves over time.
131
+ *
132
+ * Key migrations include:
133
+ * - AddUrlProp: Added URL property for direct video links
134
+ * - MakeUrlsValid: Ensured all URLs conform to link URL validation
135
+ * - AddAltText: Added accessibility support with alternative text
136
+ * - AddAutoplay: Added autoplay control for video playback
137
+ *
138
+ * @public
139
+ */
45
140
  export const videoShapeMigrations = createShapePropsMigrationSequence({
46
141
  sequence: [
47
142
  {
@@ -0,0 +1,88 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { getTestMigration } from './__tests__/migrationTestUtils'
3
+ import { storeMigrations, storeVersions } from './store-migrations'
4
+
5
+ describe('storeMigrations', () => {
6
+ it('has valid migration sequence structure', () => {
7
+ expect(storeMigrations.sequenceId).toBe('com.tldraw.store')
8
+ expect(storeMigrations.retroactive).toBe(false)
9
+ expect(storeMigrations.sequence.length).toBeGreaterThan(0)
10
+
11
+ // Verify all migrations have required fields
12
+ for (const migration of storeMigrations.sequence) {
13
+ expect(migration.id).toBeDefined()
14
+ expect(migration.scope).toBeDefined()
15
+ expect(migration.up).toBeInstanceOf(Function)
16
+ }
17
+ })
18
+ })
19
+
20
+ describe('RemoveCodeAndIconShapeTypes migration', () => {
21
+ const { up } = getTestMigration(storeVersions.RemoveCodeAndIconShapeTypes)
22
+
23
+ it('removes icon and code shapes from store', () => {
24
+ const store = {
25
+ 'shape:icon1': { typeName: 'shape', type: 'icon' },
26
+ 'shape:code1': { typeName: 'shape', type: 'code' },
27
+ 'shape:geo1': { typeName: 'shape', type: 'geo' },
28
+ 'page:test': { typeName: 'page' },
29
+ }
30
+
31
+ const result = up(store)
32
+
33
+ expect(result['shape:icon1']).toBeUndefined()
34
+ expect(result['shape:code1']).toBeUndefined()
35
+ expect(result['shape:geo1']).toBeDefined()
36
+ expect(result['page:test']).toBeDefined()
37
+ })
38
+ })
39
+
40
+ describe('AddInstancePresenceType migration', () => {
41
+ const { up } = getTestMigration(storeVersions.AddInstancePresenceType)
42
+
43
+ it('is a no-op migration', () => {
44
+ const store = { 'page:test': { typeName: 'page' } }
45
+ const result = up(store)
46
+ expect(result).toEqual(store)
47
+ })
48
+ })
49
+
50
+ describe('RemoveTLUserAndPresenceAndAddPointer migration', () => {
51
+ const { up } = getTestMigration(storeVersions.RemoveTLUserAndPresenceAndAddPointer)
52
+
53
+ it('removes user and user_presence records', () => {
54
+ const store = {
55
+ 'user:123': { typeName: 'user' },
56
+ 'user_presence:456': { typeName: 'user_presence' },
57
+ 'instance:789': { typeName: 'instance' },
58
+ 'user_something:abc': { typeName: 'user_something' }, // Should not match
59
+ }
60
+
61
+ const result = up(store)
62
+
63
+ expect(result['user:123']).toBeUndefined()
64
+ expect(result['user_presence:456']).toBeUndefined()
65
+ expect(result['instance:789']).toBeDefined()
66
+ expect(result['user_something:abc']).toBeDefined() // Uses exact regex match
67
+ })
68
+ })
69
+
70
+ describe('RemoveUserDocument migration', () => {
71
+ const { up } = getTestMigration(storeVersions.RemoveUserDocument)
72
+
73
+ it('removes user_document records', () => {
74
+ const store = {
75
+ 'user_document:123': { typeName: 'user_document' },
76
+ 'user_document_meta:456': { typeName: 'user_document_meta' }, // Also matches due to substring
77
+ 'document:789': { typeName: 'document' },
78
+ 'instance:abc': { typeName: 'instance' },
79
+ }
80
+
81
+ const result = up(store)
82
+
83
+ expect(result['user_document:123']).toBeUndefined()
84
+ expect(result['user_document_meta:456']).toBeUndefined() // Uses match() which finds substring
85
+ expect(result['document:789']).toBeDefined()
86
+ expect(result['instance:abc']).toBeDefined()
87
+ })
88
+ })
@@ -4,6 +4,12 @@ import { TLPage } from './records/TLPage'
4
4
  import { TLShape } from './records/TLShape'
5
5
  import { TLLineShape } from './shapes/TLLineShape'
6
6
 
7
+ /**
8
+ * Migration version constants for store-level schema changes.
9
+ * Each version represents a breaking change that requires data transformation.
10
+ *
11
+ * @internal
12
+ */
7
13
  const Versions = createMigrationIds('com.tldraw.store', {
8
14
  RemoveCodeAndIconShapeTypes: 1,
9
15
  AddInstancePresenceType: 2,
@@ -12,9 +18,49 @@ const Versions = createMigrationIds('com.tldraw.store', {
12
18
  FixIndexKeys: 5,
13
19
  } as const)
14
20
 
21
+ /**
22
+ * Migration version identifiers for store-level migrations.
23
+ * These versions track changes to the overall store structure and data model.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { storeVersions } from '@tldraw/tlschema'
28
+ *
29
+ * // Check if a specific migration version exists
30
+ * const hasRemoveCodeShapes = storeVersions.RemoveCodeAndIconShapeTypes
31
+ * ```
32
+ *
33
+ * @public
34
+ */
15
35
  export { Versions as storeVersions }
16
36
 
17
- /** @public */
37
+ /**
38
+ * Store-level migration sequence that handles evolution of the tldraw data model.
39
+ * These migrations run when the store schema version changes and ensure backward
40
+ * compatibility by transforming old data structures to new formats.
41
+ *
42
+ * The migrations handle:
43
+ * - Removal of deprecated shape types (code, icon)
44
+ * - Addition of new record types (instance presence)
45
+ * - Cleanup of obsolete user and presence data
46
+ * - Removal of deprecated user document records
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * import { storeMigrations } from '@tldraw/tlschema'
51
+ * import { migrate } from '@tldraw/store'
52
+ *
53
+ * // Apply store migrations to old data
54
+ * const migratedStore = migrate({
55
+ * store: oldStoreData,
56
+ * migrations: storeMigrations,
57
+ * fromVersion: 0,
58
+ * toVersion: storeMigrations.currentVersion
59
+ * })
60
+ * ```
61
+ *
62
+ * @public
63
+ */
18
64
  export const storeMigrations = createMigrationSequence({
19
65
  sequenceId: 'com.tldraw.store',
20
66
  retroactive: false,