@tldraw/tlschema 4.1.0-canary.e4499a57ef5b → 4.1.0-canary.f2f81cd6fe2c

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 (214) 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 +0 -10
  40. package/dist-cjs/shapes/TLEmbedShape.js.map +2 -2
  41. package/dist-cjs/shapes/TLFrameShape.js.map +2 -2
  42. package/dist-cjs/shapes/TLGeoShape.js.map +2 -2
  43. package/dist-cjs/shapes/TLGroupShape.js.map +2 -2
  44. package/dist-cjs/shapes/TLHighlightShape.js.map +2 -2
  45. package/dist-cjs/shapes/TLImageShape.js.map +2 -2
  46. package/dist-cjs/shapes/TLLineShape.js.map +2 -2
  47. package/dist-cjs/shapes/TLNoteShape.js.map +2 -2
  48. package/dist-cjs/shapes/TLTextShape.js.map +2 -2
  49. package/dist-cjs/shapes/TLVideoShape.js.map +2 -2
  50. package/dist-cjs/store-migrations.js.map +2 -2
  51. package/dist-cjs/styles/TLColorStyle.js.map +2 -2
  52. package/dist-cjs/styles/TLDashStyle.js.map +2 -2
  53. package/dist-cjs/styles/TLFillStyle.js.map +2 -2
  54. package/dist-cjs/styles/TLFontStyle.js.map +2 -2
  55. package/dist-cjs/styles/TLHorizontalAlignStyle.js.map +2 -2
  56. package/dist-cjs/styles/TLSizeStyle.js.map +2 -2
  57. package/dist-cjs/styles/TLTextAlignStyle.js.map +2 -2
  58. package/dist-cjs/styles/TLVerticalAlignStyle.js.map +2 -2
  59. package/dist-cjs/translations/translations.js +1 -1
  60. package/dist-cjs/translations/translations.js.map +2 -2
  61. package/dist-cjs/util-types.js.map +1 -1
  62. package/dist-esm/TLStore.mjs +3 -10
  63. package/dist-esm/TLStore.mjs.map +2 -2
  64. package/dist-esm/assets/TLBaseAsset.mjs.map +2 -2
  65. package/dist-esm/assets/TLBookmarkAsset.mjs.map +2 -2
  66. package/dist-esm/assets/TLImageAsset.mjs.map +2 -2
  67. package/dist-esm/assets/TLVideoAsset.mjs.map +2 -2
  68. package/dist-esm/bindings/TLArrowBinding.mjs.map +2 -2
  69. package/dist-esm/bindings/TLBaseBinding.mjs.map +2 -2
  70. package/dist-esm/createPresenceStateDerivation.mjs.map +2 -2
  71. package/dist-esm/createTLSchema.mjs.map +2 -2
  72. package/dist-esm/index.d.mts +4416 -223
  73. package/dist-esm/index.mjs +1 -1
  74. package/dist-esm/index.mjs.map +2 -2
  75. package/dist-esm/misc/TLColor.mjs.map +2 -2
  76. package/dist-esm/misc/TLCursor.mjs.map +2 -2
  77. package/dist-esm/misc/TLHandle.mjs.map +2 -2
  78. package/dist-esm/misc/TLOpacity.mjs.map +2 -2
  79. package/dist-esm/misc/TLRichText.mjs.map +2 -2
  80. package/dist-esm/misc/TLScribble.mjs.map +2 -2
  81. package/dist-esm/misc/geometry-types.mjs.map +2 -2
  82. package/dist-esm/misc/id-validator.mjs.map +2 -2
  83. package/dist-esm/records/TLAsset.mjs.map +2 -2
  84. package/dist-esm/records/TLBinding.mjs.map +2 -2
  85. package/dist-esm/records/TLCamera.mjs.map +2 -2
  86. package/dist-esm/records/TLDocument.mjs.map +2 -2
  87. package/dist-esm/records/TLInstance.mjs.map +2 -2
  88. package/dist-esm/records/TLPage.mjs.map +2 -2
  89. package/dist-esm/records/TLPageState.mjs.map +2 -2
  90. package/dist-esm/records/TLPointer.mjs.map +2 -2
  91. package/dist-esm/records/TLPresence.mjs.map +2 -2
  92. package/dist-esm/records/TLShape.mjs.map +2 -2
  93. package/dist-esm/recordsWithProps.mjs.map +2 -2
  94. package/dist-esm/shapes/TLArrowShape.mjs.map +2 -2
  95. package/dist-esm/shapes/TLBaseShape.mjs.map +2 -2
  96. package/dist-esm/shapes/TLBookmarkShape.mjs.map +2 -2
  97. package/dist-esm/shapes/TLDrawShape.mjs.map +2 -2
  98. package/dist-esm/shapes/TLEmbedShape.mjs +0 -10
  99. package/dist-esm/shapes/TLEmbedShape.mjs.map +2 -2
  100. package/dist-esm/shapes/TLFrameShape.mjs.map +2 -2
  101. package/dist-esm/shapes/TLGeoShape.mjs.map +2 -2
  102. package/dist-esm/shapes/TLGroupShape.mjs.map +2 -2
  103. package/dist-esm/shapes/TLHighlightShape.mjs.map +2 -2
  104. package/dist-esm/shapes/TLImageShape.mjs.map +2 -2
  105. package/dist-esm/shapes/TLLineShape.mjs.map +2 -2
  106. package/dist-esm/shapes/TLNoteShape.mjs.map +2 -2
  107. package/dist-esm/shapes/TLTextShape.mjs.map +2 -2
  108. package/dist-esm/shapes/TLVideoShape.mjs.map +2 -2
  109. package/dist-esm/store-migrations.mjs.map +2 -2
  110. package/dist-esm/styles/TLColorStyle.mjs.map +2 -2
  111. package/dist-esm/styles/TLDashStyle.mjs.map +2 -2
  112. package/dist-esm/styles/TLFillStyle.mjs.map +2 -2
  113. package/dist-esm/styles/TLFontStyle.mjs.map +2 -2
  114. package/dist-esm/styles/TLHorizontalAlignStyle.mjs.map +2 -2
  115. package/dist-esm/styles/TLSizeStyle.mjs.map +2 -2
  116. package/dist-esm/styles/TLTextAlignStyle.mjs.map +2 -2
  117. package/dist-esm/styles/TLVerticalAlignStyle.mjs.map +2 -2
  118. package/dist-esm/translations/translations.mjs +1 -1
  119. package/dist-esm/translations/translations.mjs.map +2 -2
  120. package/package.json +5 -5
  121. package/src/TLStore.test.ts +644 -0
  122. package/src/TLStore.ts +205 -20
  123. package/src/assets/TLBaseAsset.ts +90 -7
  124. package/src/assets/TLBookmarkAsset.test.ts +96 -0
  125. package/src/assets/TLBookmarkAsset.ts +52 -2
  126. package/src/assets/TLImageAsset.test.ts +213 -0
  127. package/src/assets/TLImageAsset.ts +60 -2
  128. package/src/assets/TLVideoAsset.test.ts +105 -0
  129. package/src/assets/TLVideoAsset.ts +93 -4
  130. package/src/bindings/TLArrowBinding.test.ts +55 -0
  131. package/src/bindings/TLArrowBinding.ts +132 -10
  132. package/src/bindings/TLBaseBinding.ts +140 -3
  133. package/src/createPresenceStateDerivation.test.ts +158 -0
  134. package/src/createPresenceStateDerivation.ts +71 -2
  135. package/src/createTLSchema.test.ts +181 -0
  136. package/src/createTLSchema.ts +164 -7
  137. package/src/index.ts +32 -0
  138. package/src/misc/TLColor.ts +50 -6
  139. package/src/misc/TLCursor.ts +110 -8
  140. package/src/misc/TLHandle.ts +86 -6
  141. package/src/misc/TLOpacity.ts +51 -2
  142. package/src/misc/TLRichText.ts +56 -3
  143. package/src/misc/TLScribble.ts +105 -5
  144. package/src/misc/geometry-types.ts +30 -2
  145. package/src/misc/id-validator.test.ts +50 -0
  146. package/src/misc/id-validator.ts +20 -1
  147. package/src/records/TLAsset.test.ts +234 -0
  148. package/src/records/TLAsset.ts +165 -8
  149. package/src/records/TLBinding.test.ts +22 -0
  150. package/src/records/TLBinding.ts +277 -11
  151. package/src/records/TLCamera.test.ts +19 -0
  152. package/src/records/TLCamera.ts +118 -7
  153. package/src/records/TLDocument.test.ts +35 -0
  154. package/src/records/TLDocument.ts +148 -8
  155. package/src/records/TLInstance.test.ts +201 -0
  156. package/src/records/TLInstance.ts +117 -9
  157. package/src/records/TLPage.test.ts +110 -0
  158. package/src/records/TLPage.ts +106 -8
  159. package/src/records/TLPageState.test.ts +228 -0
  160. package/src/records/TLPageState.ts +88 -7
  161. package/src/records/TLPointer.test.ts +63 -0
  162. package/src/records/TLPointer.ts +105 -7
  163. package/src/records/TLPresence.test.ts +190 -0
  164. package/src/records/TLPresence.ts +99 -5
  165. package/src/records/TLRecord.test.ts +70 -0
  166. package/src/records/TLRecord.ts +43 -1
  167. package/src/records/TLShape.test.ts +232 -0
  168. package/src/records/TLShape.ts +289 -12
  169. package/src/recordsWithProps.test.ts +188 -0
  170. package/src/recordsWithProps.ts +131 -2
  171. package/src/shapes/ShapeWithCrop.test.ts +18 -0
  172. package/src/shapes/ShapeWithCrop.ts +64 -2
  173. package/src/shapes/TLArrowShape.test.ts +505 -0
  174. package/src/shapes/TLArrowShape.ts +188 -10
  175. package/src/shapes/TLBaseShape.test.ts +142 -0
  176. package/src/shapes/TLBaseShape.ts +103 -4
  177. package/src/shapes/TLBookmarkShape.test.ts +122 -0
  178. package/src/shapes/TLBookmarkShape.ts +58 -4
  179. package/src/shapes/TLDrawShape.test.ts +177 -0
  180. package/src/shapes/TLDrawShape.ts +97 -6
  181. package/src/shapes/TLEmbedShape.test.ts +286 -0
  182. package/src/shapes/TLEmbedShape.ts +57 -14
  183. package/src/shapes/TLFrameShape.test.ts +71 -0
  184. package/src/shapes/TLFrameShape.ts +59 -4
  185. package/src/shapes/TLGeoShape.test.ts +247 -0
  186. package/src/shapes/TLGeoShape.ts +103 -7
  187. package/src/shapes/TLGroupShape.test.ts +59 -0
  188. package/src/shapes/TLGroupShape.ts +52 -4
  189. package/src/shapes/TLHighlightShape.test.ts +325 -0
  190. package/src/shapes/TLHighlightShape.ts +79 -4
  191. package/src/shapes/TLImageShape.test.ts +534 -0
  192. package/src/shapes/TLImageShape.ts +105 -5
  193. package/src/shapes/TLLineShape.test.ts +269 -0
  194. package/src/shapes/TLLineShape.ts +128 -8
  195. package/src/shapes/TLNoteShape.test.ts +1568 -0
  196. package/src/shapes/TLNoteShape.ts +97 -4
  197. package/src/shapes/TLTextShape.test.ts +407 -0
  198. package/src/shapes/TLTextShape.ts +94 -4
  199. package/src/shapes/TLVideoShape.test.ts +112 -0
  200. package/src/shapes/TLVideoShape.ts +99 -4
  201. package/src/store-migrations.test.ts +88 -0
  202. package/src/store-migrations.ts +47 -1
  203. package/src/styles/TLColorStyle.test.ts +439 -0
  204. package/src/styles/TLColorStyle.ts +228 -10
  205. package/src/styles/TLDashStyle.ts +54 -2
  206. package/src/styles/TLFillStyle.ts +54 -2
  207. package/src/styles/TLFontStyle.ts +72 -3
  208. package/src/styles/TLHorizontalAlignStyle.ts +55 -2
  209. package/src/styles/TLSizeStyle.ts +54 -2
  210. package/src/styles/TLTextAlignStyle.ts +52 -2
  211. package/src/styles/TLVerticalAlignStyle.ts +52 -2
  212. package/src/translations/translations.test.ts +378 -35
  213. package/src/translations/translations.ts +157 -10
  214. package/src/util-types.ts +51 -1
@@ -14,25 +14,91 @@ import { TLPropsMigrations } from '../recordsWithProps'
14
14
 
15
15
  /**
16
16
  * The default set of bindings that are available in the editor.
17
+ * Currently includes only arrow bindings, but can be extended with custom bindings.
17
18
  *
18
- * @public */
19
+ * @example
20
+ * ```ts
21
+ * // Arrow binding connects an arrow to shapes
22
+ * const arrowBinding: TLDefaultBinding = {
23
+ * id: 'binding:arrow1',
24
+ * typeName: 'binding',
25
+ * type: 'arrow',
26
+ * fromId: 'shape:arrow1',
27
+ * toId: 'shape:rectangle1',
28
+ * props: {
29
+ * terminal: 'end',
30
+ * normalizedAnchor: { x: 0.5, y: 0.5 },
31
+ * isExact: false,
32
+ * isPrecise: true
33
+ * }
34
+ * }
35
+ * ```
36
+ *
37
+ * @public
38
+ */
19
39
  export type TLDefaultBinding = TLArrowBinding
20
40
 
21
41
  /**
22
42
  * A type for a binding that is available in the editor but whose type is
23
43
  * unknown—either one of the editor's default bindings or else a custom binding.
44
+ * Used internally for type-safe handling of bindings with unknown structure.
24
45
  *
25
- * @public */
46
+ * @example
47
+ * ```ts
48
+ * // Function that works with any binding type
49
+ * function processBinding(binding: TLUnknownBinding) {
50
+ * console.log(`Processing ${binding.type} binding from ${binding.fromId} to ${binding.toId}`)
51
+ * // Handle binding properties generically
52
+ * }
53
+ * ```
54
+ *
55
+ * @public
56
+ */
26
57
  export type TLUnknownBinding = TLBaseBinding<string, object>
27
58
 
28
59
  /**
29
60
  * The set of all bindings that are available in the editor, including unknown bindings.
61
+ * Bindings represent relationships between shapes, such as arrows connecting to other shapes.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * // Check binding type and handle accordingly
66
+ * function handleBinding(binding: TLBinding) {
67
+ * switch (binding.type) {
68
+ * case 'arrow':
69
+ * // Handle arrow binding
70
+ * break
71
+ * default:
72
+ * // Handle unknown custom binding
73
+ * break
74
+ * }
75
+ * }
76
+ * ```
30
77
  *
31
78
  * @public
32
79
  */
33
80
  export type TLBinding = TLDefaultBinding | TLUnknownBinding
34
81
 
35
- /** @public */
82
+ /**
83
+ * Type for updating existing bindings with partial properties.
84
+ * Only the id and type are required, all other properties are optional.
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * // Update arrow binding properties
89
+ * const bindingUpdate: TLBindingUpdate<TLArrowBinding> = {
90
+ * id: 'binding:arrow1',
91
+ * type: 'arrow',
92
+ * props: {
93
+ * normalizedAnchor: { x: 0.7, y: 0.3 } // Only update anchor position
94
+ * }
95
+ * }
96
+ *
97
+ * editor.updateBindings([bindingUpdate])
98
+ * ```
99
+ *
100
+ * @public
101
+ */
36
102
  export type TLBindingUpdate<T extends TLBinding = TLBinding> = Expand<{
37
103
  id: TLBindingId
38
104
  type: T['type']
@@ -43,7 +109,30 @@ export type TLBindingUpdate<T extends TLBinding = TLBinding> = Expand<{
43
109
  meta?: Partial<T['meta']>
44
110
  }>
45
111
 
46
- /** @public */
112
+ /**
113
+ * Type for creating new bindings with required fromId and toId.
114
+ * The id is optional and will be generated if not provided.
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * // Create a new arrow binding
119
+ * const newBinding: TLBindingCreate<TLArrowBinding> = {
120
+ * type: 'arrow',
121
+ * fromId: 'shape:arrow1',
122
+ * toId: 'shape:rectangle1',
123
+ * props: {
124
+ * terminal: 'end',
125
+ * normalizedAnchor: { x: 0.5, y: 0.5 },
126
+ * isExact: false,
127
+ * isPrecise: true
128
+ * }
129
+ * }
130
+ *
131
+ * editor.createBindings([newBinding])
132
+ * ```
133
+ *
134
+ * @public
135
+ */
47
136
  export type TLBindingCreate<T extends TLBinding = TLBinding> = Expand<{
48
137
  id?: TLBindingId
49
138
  type: T['type']
@@ -55,40 +144,176 @@ export type TLBindingCreate<T extends TLBinding = TLBinding> = Expand<{
55
144
  }>
56
145
 
57
146
  /**
58
- * An ID for a {@link TLBinding}.
147
+ * Branded string type for binding record identifiers.
148
+ * Prevents mixing binding IDs with other types of record IDs at compile time.
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * import { createBindingId } from '@tldraw/tlschema'
153
+ *
154
+ * // Create a new binding ID
155
+ * const bindingId: TLBindingId = createBindingId()
156
+ *
157
+ * // Use in binding records
158
+ * const binding: TLBinding = {
159
+ * id: bindingId,
160
+ * type: 'arrow',
161
+ * fromId: 'shape:arrow1',
162
+ * toId: 'shape:rectangle1',
163
+ * // ... other properties
164
+ * }
165
+ * ```
59
166
  *
60
167
  * @public
61
168
  */
62
169
  export type TLBindingId = RecordId<TLUnknownBinding>
63
170
 
64
- /** @public */
171
+ /**
172
+ * Migration version identifiers for the root binding record schema.
173
+ * Currently empty as no migrations have been applied to the base binding structure.
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * // Future migrations would be defined here
178
+ * const rootBindingVersions = createMigrationIds('com.tldraw.binding', {
179
+ * AddNewProperty: 1,
180
+ * } as const)
181
+ * ```
182
+ *
183
+ * @public
184
+ */
65
185
  export const rootBindingVersions = createMigrationIds('com.tldraw.binding', {} as const)
66
186
 
67
- /** @public */
187
+ /**
188
+ * Migration sequence for the root binding record structure.
189
+ * Currently empty as the binding schema has not required any migrations yet.
190
+ *
191
+ * @example
192
+ * ```ts
193
+ * // Migrations would be automatically applied when loading old documents
194
+ * const migratedStore = migrator.migrateStoreSnapshot({
195
+ * schema: oldSchema,
196
+ * store: oldStoreSnapshot
197
+ * })
198
+ * ```
199
+ *
200
+ * @public
201
+ */
68
202
  export const rootBindingMigrations = createRecordMigrationSequence({
69
203
  sequenceId: 'com.tldraw.binding',
70
204
  recordType: 'binding',
71
205
  sequence: [],
72
206
  })
73
207
 
74
- /** @public */
208
+ /**
209
+ * Type guard to check if a record is a TLBinding.
210
+ * Useful for filtering or type narrowing when working with mixed record types.
211
+ *
212
+ * @param record - The record to check
213
+ * @returns True if the record is a binding, false otherwise
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * // Filter bindings from mixed records
218
+ * const allRecords = store.allRecords()
219
+ * const bindings = allRecords.filter(isBinding)
220
+ *
221
+ * // Type guard usage
222
+ * function processRecord(record: UnknownRecord) {
223
+ * if (isBinding(record)) {
224
+ * // record is now typed as TLBinding
225
+ * console.log(`Binding from ${record.fromId} to ${record.toId}`)
226
+ * }
227
+ * }
228
+ * ```
229
+ *
230
+ * @public
231
+ */
75
232
  export function isBinding(record?: UnknownRecord): record is TLBinding {
76
233
  if (!record) return false
77
234
  return record.typeName === 'binding'
78
235
  }
79
236
 
80
- /** @public */
237
+ /**
238
+ * Type guard to check if a string is a valid TLBindingId.
239
+ * Validates that the ID follows the correct format for binding identifiers.
240
+ *
241
+ * @param id - The string to check
242
+ * @returns True if the string is a valid binding ID, false otherwise
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * // Validate binding IDs
247
+ * const maybeBindingId = 'binding:abc123'
248
+ * if (isBindingId(maybeBindingId)) {
249
+ * // maybeBindingId is now typed as TLBindingId
250
+ * const binding = store.get(maybeBindingId)
251
+ * }
252
+ *
253
+ * // Filter binding IDs from mixed ID array
254
+ * const mixedIds = ['shape:1', 'binding:2', 'page:3']
255
+ * const bindingIds = mixedIds.filter(isBindingId)
256
+ * ```
257
+ *
258
+ * @public
259
+ */
81
260
  export function isBindingId(id?: string): id is TLBindingId {
82
261
  if (!id) return false
83
262
  return id.startsWith('binding:')
84
263
  }
85
264
 
86
- /** @public */
265
+ /**
266
+ * Creates a new TLBindingId with proper formatting.
267
+ * Generates a unique ID if none is provided, or formats a provided ID correctly.
268
+ *
269
+ * @param id - Optional custom ID suffix. If not provided, a unique ID is generated
270
+ * @returns A properly formatted binding ID
271
+ *
272
+ * @example
273
+ * ```ts
274
+ * // Create with auto-generated ID
275
+ * const bindingId1 = createBindingId() // 'binding:abc123'
276
+ *
277
+ * // Create with custom ID
278
+ * const bindingId2 = createBindingId('myCustomBinding') // 'binding:myCustomBinding'
279
+ *
280
+ * // Use in binding creation
281
+ * const binding: TLBinding = {
282
+ * id: createBindingId(),
283
+ * type: 'arrow',
284
+ * fromId: 'shape:arrow1',
285
+ * toId: 'shape:rectangle1',
286
+ * // ... other properties
287
+ * }
288
+ * ```
289
+ *
290
+ * @public
291
+ */
87
292
  export function createBindingId(id?: string): TLBindingId {
88
293
  return `binding:${id ?? uniqueId()}` as TLBindingId
89
294
  }
90
295
 
91
296
  /**
297
+ * Creates a migration sequence for binding properties.
298
+ * This is a pass-through function that validates and returns the provided migrations.
299
+ *
300
+ * @param migrations - The migration sequence for binding properties
301
+ * @returns The validated migration sequence
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * // Define migrations for custom binding properties
306
+ * const myBindingMigrations = createBindingPropsMigrationSequence({
307
+ * sequence: [
308
+ * {
309
+ * id: 'com.myapp.binding.custom/1.0.0',
310
+ * up: (props) => ({ ...props, newProperty: 'default' }),
311
+ * down: ({ newProperty, ...props }) => props
312
+ * }
313
+ * ]
314
+ * })
315
+ * ```
316
+ *
92
317
  * @public
93
318
  */
94
319
  export function createBindingPropsMigrationSequence(
@@ -98,6 +323,28 @@ export function createBindingPropsMigrationSequence(
98
323
  }
99
324
 
100
325
  /**
326
+ * Creates properly formatted migration IDs for binding property migrations.
327
+ * Follows the convention: 'com.tldraw.binding.\{bindingType\}/\{version\}'
328
+ *
329
+ * @param bindingType - The type of binding these migrations apply to
330
+ * @param ids - Object mapping migration names to version numbers
331
+ * @returns Object with formatted migration IDs
332
+ *
333
+ * @example
334
+ * ```ts
335
+ * // Create migration IDs for custom binding
336
+ * const myBindingVersions = createBindingPropsMigrationIds('myCustomBinding', {
337
+ * AddNewProperty: 1,
338
+ * UpdateProperty: 2
339
+ * })
340
+ *
341
+ * // Result:
342
+ * // {
343
+ * // AddNewProperty: 'com.tldraw.binding.myCustomBinding/1',
344
+ * // UpdateProperty: 'com.tldraw.binding.myCustomBinding/2'
345
+ * // }
346
+ * ```
347
+ *
101
348
  * @public
102
349
  */
103
350
  export function createBindingPropsMigrationIds<S extends string, T extends Record<string, number>>(
@@ -107,7 +354,26 @@ export function createBindingPropsMigrationIds<S extends string, T extends Recor
107
354
  return mapObjectMapValues(ids, (_k, v) => `com.tldraw.binding.${bindingType}/${v}`) as any
108
355
  }
109
356
 
110
- /** @internal */
357
+ /**
358
+ * Creates a record type for TLBinding with validation based on the provided binding schemas.
359
+ * This function is used internally to configure the binding record type in the schema.
360
+ *
361
+ * @param bindings - Record mapping binding type names to their schema information
362
+ * @returns A configured record type for bindings with validation
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * // Used internally when creating schemas
367
+ * const bindingRecordType = createBindingRecordType({
368
+ * arrow: {
369
+ * props: arrowBindingProps,
370
+ * meta: arrowBindingMeta
371
+ * }
372
+ * })
373
+ * ```
374
+ *
375
+ * @internal
376
+ */
111
377
  export function createBindingRecordType(bindings: Record<string, SchemaPropsInfo>) {
112
378
  return createRecordType<TLBinding>('binding', {
113
379
  scope: 'document',
@@ -0,0 +1,19 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { cameraMigrations, cameraVersions } from './TLCamera'
3
+
4
+ describe('cameraMigrations', () => {
5
+ it('should apply AddMeta migration correctly', () => {
6
+ const addMetaMigration = cameraMigrations.sequence.find((m) => m.id === cameraVersions.AddMeta)!
7
+
8
+ const oldRecord: any = {
9
+ typeName: 'camera',
10
+ id: 'camera:test',
11
+ x: 100,
12
+ y: 200,
13
+ z: 0.5,
14
+ }
15
+
16
+ addMetaMigration.up(oldRecord)
17
+ expect(oldRecord.meta).toEqual({})
18
+ })
19
+ })
@@ -10,24 +10,84 @@ import { T } from '@tldraw/validate'
10
10
  import { idValidator } from '../misc/id-validator'
11
11
 
12
12
  /**
13
- * A camera record.
13
+ * A camera record representing the viewport's position and zoom level.
14
+ * The camera defines what portion of the infinite canvas is visible to the user.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const camera: TLCamera = {
19
+ * id: 'camera:user1',
20
+ * typeName: 'camera',
21
+ * x: 100, // Camera x position (negative values pan right)
22
+ * y: 50, // Camera y position (negative values pan down)
23
+ * z: 0.5, // Zoom level (1 = 100%, 0.5 = 50%, 2 = 200%)
24
+ * meta: {
25
+ * userId: 'user123',
26
+ * lastUpdated: Date.now()
27
+ * }
28
+ * }
29
+ *
30
+ * // Set camera position and zoom
31
+ * editor.setCamera({ x: -200, y: -100, z: 1.5 })
32
+ * ```
14
33
  *
15
34
  * @public
16
35
  */
17
36
  export interface TLCamera extends BaseRecord<'camera', TLCameraId> {
37
+ /** Camera x position. Negative values move the viewport right */
18
38
  x: number
39
+ /** Camera y position. Negative values move the viewport down */
19
40
  y: number
41
+ /** Zoom level. 1 = 100%, 0.5 = 50% zoom, 2 = 200% zoom */
20
42
  z: number
43
+ /** User-defined metadata for the camera */
21
44
  meta: JsonObject
22
45
  }
23
46
 
24
47
  /**
25
- * The id of a camera record.
48
+ * Branded string type for camera record identifiers.
49
+ * Prevents mixing camera IDs with other types of record IDs at compile time.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * import { CameraRecordType } from '@tldraw/tlschema'
54
+ *
55
+ * // Create a camera ID (typically one per user/session)
56
+ * const cameraId: TLCameraId = CameraRecordType.createId()
26
57
  *
27
- * @public */
58
+ * // Use in camera records
59
+ * const camera: TLCamera = {
60
+ * id: cameraId,
61
+ * typeName: 'camera',
62
+ * x: 0, y: 0, z: 1,
63
+ * meta: {}
64
+ * }
65
+ *
66
+ * // Get camera from store
67
+ * const currentCamera = store.get(cameraId)
68
+ * ```
69
+ *
70
+ * @public
71
+ */
28
72
  export type TLCameraId = RecordId<TLCamera>
29
73
 
30
- /** @public */
74
+ /**
75
+ * Validator for TLCamera records that ensures runtime type safety.
76
+ * Validates camera position coordinates and zoom level.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * // Validation happens automatically when cameras are stored
81
+ * try {
82
+ * const validatedCamera = cameraValidator.validate(cameraData)
83
+ * store.put([validatedCamera])
84
+ * } catch (error) {
85
+ * console.error('Camera validation failed:', error.message)
86
+ * }
87
+ * ```
88
+ *
89
+ * @public
90
+ */
31
91
  export const cameraValidator: T.Validator<TLCamera> = T.model(
32
92
  'camera',
33
93
  T.object({
@@ -40,12 +100,37 @@ export const cameraValidator: T.Validator<TLCamera> = T.model(
40
100
  })
41
101
  )
42
102
 
43
- /** @public */
103
+ /**
104
+ * Migration version identifiers for camera record schema evolution.
105
+ * Each version represents a breaking change that requires data migration.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * // Check if a camera needs migration
110
+ * const needsMigration = currentVersion < cameraVersions.AddMeta
111
+ * ```
112
+ *
113
+ * @public
114
+ */
44
115
  export const cameraVersions = createMigrationIds('com.tldraw.camera', {
45
116
  AddMeta: 1,
46
117
  })
47
118
 
48
- /** @public */
119
+ /**
120
+ * Migration sequence for evolving camera record structure over time.
121
+ * Handles converting camera records from older schema versions to current format.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * // Migration is applied automatically when loading old documents
126
+ * const migratedStore = migrator.migrateStoreSnapshot({
127
+ * schema: oldSchema,
128
+ * store: oldStoreSnapshot
129
+ * })
130
+ * ```
131
+ *
132
+ * @public
133
+ */
49
134
  export const cameraMigrations = createRecordMigrationSequence({
50
135
  sequenceId: 'com.tldraw.camera',
51
136
  recordType: 'camera',
@@ -59,7 +144,33 @@ export const cameraMigrations = createRecordMigrationSequence({
59
144
  ],
60
145
  })
61
146
 
62
- /** @public */
147
+ /**
148
+ * Record type definition for TLCamera with validation and default properties.
149
+ * Configures cameras as session-scoped records that don't persist across sessions.
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * // Create a new camera record with defaults
154
+ * const cameraRecord = CameraRecordType.create({
155
+ * id: 'camera:main'
156
+ * // x: 0, y: 0, z: 1, meta: {} are applied as defaults
157
+ * })
158
+ *
159
+ * // Create with custom position and zoom
160
+ * const customCamera = CameraRecordType.create({
161
+ * id: 'camera:user1',
162
+ * x: -100,
163
+ * y: -50,
164
+ * z: 1.5,
165
+ * meta: { userId: 'user123' }
166
+ * })
167
+ *
168
+ * // Store the camera
169
+ * store.put([cameraRecord])
170
+ * ```
171
+ *
172
+ * @public
173
+ */
63
174
  export const CameraRecordType = createRecordType<TLCamera>('camera', {
64
175
  validator: cameraValidator,
65
176
  scope: 'session',
@@ -0,0 +1,35 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { documentMigrations, documentVersions, TLDOCUMENT_ID } from './TLDocument'
3
+
4
+ describe('documentMigrations', () => {
5
+ it('should apply AddName migration correctly', () => {
6
+ const addNameMigration = documentMigrations.sequence.find(
7
+ (m) => m.id === documentVersions.AddName
8
+ )!
9
+
10
+ const oldRecord: any = {
11
+ typeName: 'document',
12
+ id: TLDOCUMENT_ID,
13
+ gridSize: 10,
14
+ }
15
+
16
+ addNameMigration.up(oldRecord)
17
+ expect(oldRecord.name).toBe('')
18
+ })
19
+
20
+ it('should apply AddMeta migration correctly', () => {
21
+ const addMetaMigration = documentMigrations.sequence.find(
22
+ (m) => m.id === documentVersions.AddMeta
23
+ )!
24
+
25
+ const oldRecord: any = {
26
+ typeName: 'document',
27
+ id: TLDOCUMENT_ID,
28
+ gridSize: 10,
29
+ name: 'Test',
30
+ }
31
+
32
+ addMetaMigration.up(oldRecord)
33
+ expect(oldRecord.meta).toEqual({})
34
+ })
35
+ })