@tldraw/tlschema 4.1.0-canary.af5f4bce7236 → 4.1.0-canary.b1f18f73aceb

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
@@ -19,7 +19,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var TLStore_exports = {};
20
20
  __export(TLStore_exports, {
21
21
  createIntegrityChecker: () => createIntegrityChecker,
22
- onValidationFailure: () => onValidationFailure
22
+ onValidationFailure: () => onValidationFailure,
23
+ redactRecordForErrorReporting: () => redactRecordForErrorReporting
23
24
  });
24
25
  module.exports = __toCommonJS(TLStore_exports);
25
26
  var import_utils = require("@tldraw/utils");
@@ -29,14 +30,6 @@ var import_TLInstance = require("./records/TLInstance");
29
30
  var import_TLPage = require("./records/TLPage");
30
31
  var import_TLPageState = require("./records/TLPageState");
31
32
  var import_TLPointer = require("./records/TLPointer");
32
- function sortByIndex(a, b) {
33
- if (a.index < b.index) {
34
- return -1;
35
- } else if (a.index > b.index) {
36
- return 1;
37
- }
38
- return 0;
39
- }
40
33
  function redactRecordForErrorReporting(record) {
41
34
  if (record.typeName === "asset") {
42
35
  if ("src" in record) {
@@ -98,7 +91,7 @@ function createIntegrityChecker(store) {
98
91
  store.put(getDefaultPages());
99
92
  return ensureStoreIsUsable();
100
93
  }
101
- const getFirstPageId = () => [...pageIds].map((id) => store.get(id)).sort(sortByIndex)[0].id;
94
+ const getFirstPageId = () => [...pageIds].map((id) => store.get(id)).sort(import_utils.sortByIndex)[0].id;
102
95
  const instanceState = store.get(import_TLInstance.TLINSTANCE_ID);
103
96
  if (!instanceState) {
104
97
  store.put([
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/TLStore.ts"],
4
- "sourcesContent": ["import { Signal } from '@tldraw/state'\nimport {\n\tSerializedStore,\n\tStore,\n\tStoreSchema,\n\tStoreSnapshot,\n\tStoreValidationFailure,\n} from '@tldraw/store'\nimport { IndexKey, JsonObject, annotateError, structuredClone } from '@tldraw/utils'\nimport { TLAsset, TLAssetId } from './records/TLAsset'\nimport { CameraRecordType, TLCameraId } from './records/TLCamera'\nimport { DocumentRecordType, TLDOCUMENT_ID } from './records/TLDocument'\nimport { TLINSTANCE_ID } from './records/TLInstance'\nimport { PageRecordType, TLPageId } from './records/TLPage'\nimport { InstancePageStateRecordType, TLInstancePageStateId } from './records/TLPageState'\nimport { PointerRecordType, TLPOINTER_ID } from './records/TLPointer'\nimport { TLRecord } from './records/TLRecord'\n\nfunction sortByIndex<T extends { index: string }>(a: T, b: T) {\n\tif (a.index < b.index) {\n\t\treturn -1\n\t} else if (a.index > b.index) {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunction redactRecordForErrorReporting(record: any) {\n\tif (record.typeName === 'asset') {\n\t\tif ('src' in record) {\n\t\t\trecord.src = '<redacted>'\n\t\t}\n\n\t\tif ('src' in record.props) {\n\t\t\trecord.props.src = '<redacted>'\n\t\t}\n\t}\n}\n\n/** @public */\nexport type TLStoreSchema = StoreSchema<TLRecord, TLStoreProps>\n\n/** @public */\nexport type TLSerializedStore = SerializedStore<TLRecord>\n\n/** @public */\nexport type TLStoreSnapshot = StoreSnapshot<TLRecord>\n\n/** @public */\nexport interface TLAssetContext {\n\t/**\n\t * The scale at which the asset is being rendered on-screen relative to its native dimensions.\n\t * If the asset is 1000px wide, but it's been resized/zoom so it takes 500px on-screen, this\n\t * will be 0.5.\n\t *\n\t * The scale measures CSS pixels, not device pixels.\n\t */\n\tscreenScale: number\n\t/** The {@link TLAssetContext.screenScale}, stepped to the nearest power-of-2 multiple. */\n\tsteppedScreenScale: number\n\t/** The device pixel ratio - how many CSS pixels are in one device pixel? */\n\tdpr: number\n\t/**\n\t * An alias for\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType | `navigator.connection.effectiveType` }\n\t * if it's available in the current browser. Use this to e.g. serve lower-resolution images to\n\t * users on slow connections.\n\t */\n\tnetworkEffectiveType: string | null\n\t/**\n\t * In some circumstances, we need to resolve a URL that points to the original version of a\n\t * particular asset. This is used when the asset will leave the current tldraw instance - e.g.\n\t * for copy/paste, or exports.\n\t */\n\tshouldResolveToOriginal: boolean\n}\n\n/**\n * A `TLAssetStore` sits alongside the main {@link TLStore} and is responsible for storing and\n * retrieving large assets such as images. Generally, this should be part of a wider sync system:\n *\n * - By default, the store is in-memory only, so `TLAssetStore` converts images to data URLs\n * - When using\n * {@link @tldraw/editor#TldrawEditorWithoutStoreProps.persistenceKey | `persistenceKey`}, the\n * store is synced to the browser's local IndexedDB, so `TLAssetStore` stores images there too\n * - When using a multiplayer sync server, you would implement `TLAssetStore` to upload images to\n * e.g. an S3 bucket.\n *\n * @public\n */\nexport interface TLAssetStore {\n\t/**\n\t * Upload an asset to your storage, returning a URL that can be used to refer to the asset\n\t * long-term.\n\t *\n\t * @param asset - Information & metadata about the asset being uploaded\n\t * @param file - The `File` to be uploaded\n\t * @returns A promise that resolves to the URL of the uploaded asset\n\t */\n\tupload(\n\t\tasset: TLAsset,\n\t\tfile: File,\n\t\tabortSignal?: AbortSignal\n\t): Promise<{ src: string; meta?: JsonObject }>\n\t/**\n\t * Resolve an asset to a URL. This is used when rendering the asset in the editor. By default,\n\t * this will just use `asset.props.src`, the URL returned by `upload()`. This can be used to\n\t * rewrite that URL to add access credentials, or optimized the asset for how it's currently\n\t * being displayed using the {@link TLAssetContext | information provided}.\n\t *\n\t * @param asset - the asset being resolved\n\t * @param ctx - information about the current environment and where the asset is being used\n\t * @returns The URL of the resolved asset, or `null` if the asset is not available\n\t */\n\tresolve?(asset: TLAsset, ctx: TLAssetContext): Promise<string | null> | string | null\n\t/**\n\t * Remove an asset from storage. This is called when the asset is no longer needed, e.g. when\n\t * the user deletes it from the editor.\n\t * @param asset - the asset being removed\n\t * @returns A promise that resolves when the asset has been removed\n\t */\n\tremove?(assetIds: TLAssetId[]): Promise<void>\n}\n\n/** @public */\nexport interface TLStoreProps {\n\tdefaultName: string\n\tassets: Required<TLAssetStore>\n\t/**\n\t * Called an {@link @tldraw/editor#Editor} connected to this store is mounted.\n\t */\n\tonMount(editor: unknown): void | (() => void)\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n}\n\n/** @public */\nexport type TLStore = Store<TLRecord, TLStoreProps>\n\n/** @public */\nexport function onValidationFailure({\n\terror,\n\tphase,\n\trecord,\n\trecordBefore,\n}: StoreValidationFailure<TLRecord>): TLRecord {\n\tconst isExistingValidationIssue =\n\t\t// if we're initializing the store for the first time, we should\n\t\t// allow invalid records so people can load old buggy data:\n\t\tphase === 'initialize'\n\n\tannotateError(error, {\n\t\ttags: {\n\t\t\torigin: 'store.validateRecord',\n\t\t\tstorePhase: phase,\n\t\t\tisExistingValidationIssue,\n\t\t},\n\t\textras: {\n\t\t\trecordBefore: recordBefore\n\t\t\t\t? redactRecordForErrorReporting(structuredClone(recordBefore))\n\t\t\t\t: undefined,\n\t\t\trecordAfter: redactRecordForErrorReporting(structuredClone(record)),\n\t\t},\n\t})\n\n\tthrow error\n}\n\nfunction getDefaultPages() {\n\treturn [\n\t\tPageRecordType.create({\n\t\t\tid: 'page:page' as TLPageId,\n\t\t\tname: 'Page 1',\n\t\t\tindex: 'a1' as IndexKey,\n\t\t\tmeta: {},\n\t\t}),\n\t]\n}\n\n/** @internal */\nexport function createIntegrityChecker(store: Store<TLRecord, TLStoreProps>): () => void {\n\tconst $pageIds = store.query.ids('page')\n\tconst $pageStates = store.query.records('instance_page_state')\n\n\tconst ensureStoreIsUsable = (): void => {\n\t\t// make sure we have exactly one document\n\t\tif (!store.has(TLDOCUMENT_ID)) {\n\t\t\tstore.put([DocumentRecordType.create({ id: TLDOCUMENT_ID, name: store.props.defaultName })])\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\tif (!store.has(TLPOINTER_ID)) {\n\t\t\tstore.put([PointerRecordType.create({ id: TLPOINTER_ID })])\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\t// make sure there is at least one page\n\t\tconst pageIds = $pageIds.get()\n\t\tif (pageIds.size === 0) {\n\t\t\tstore.put(getDefaultPages())\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\tconst getFirstPageId = () => [...pageIds].map((id) => store.get(id)!).sort(sortByIndex)[0].id!\n\n\t\t// make sure we have state for the current user's current tab\n\t\tconst instanceState = store.get(TLINSTANCE_ID)\n\t\tif (!instanceState) {\n\t\t\tstore.put([\n\t\t\t\tstore.schema.types.instance.create({\n\t\t\t\t\tid: TLINSTANCE_ID,\n\t\t\t\t\tcurrentPageId: getFirstPageId(),\n\t\t\t\t\texportBackground: true,\n\t\t\t\t}),\n\t\t\t])\n\n\t\t\treturn ensureStoreIsUsable()\n\t\t} else if (!pageIds.has(instanceState.currentPageId)) {\n\t\t\tstore.put([{ ...instanceState, currentPageId: getFirstPageId() }])\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\t// make sure we have page states and cameras for all the pages\n\t\tconst missingPageStateIds = new Set<TLInstancePageStateId>()\n\t\tconst missingCameraIds = new Set<TLCameraId>()\n\t\tfor (const id of pageIds) {\n\t\t\tconst pageStateId = InstancePageStateRecordType.createId(id)\n\t\t\tconst pageState = store.get(pageStateId)\n\t\t\tif (!pageState) {\n\t\t\t\tmissingPageStateIds.add(pageStateId)\n\t\t\t}\n\t\t\tconst cameraId = CameraRecordType.createId(id)\n\t\t\tif (!store.has(cameraId)) {\n\t\t\t\tmissingCameraIds.add(cameraId)\n\t\t\t}\n\t\t}\n\n\t\tif (missingPageStateIds.size > 0) {\n\t\t\tstore.put(\n\t\t\t\t[...missingPageStateIds].map((id) =>\n\t\t\t\t\tInstancePageStateRecordType.create({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tpageId: InstancePageStateRecordType.parseId(id) as TLPageId,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\n\t\tif (missingCameraIds.size > 0) {\n\t\t\tstore.put([...missingCameraIds].map((id) => CameraRecordType.create({ id })))\n\t\t}\n\n\t\tconst pageStates = $pageStates.get()\n\t\tfor (const pageState of pageStates) {\n\t\t\tif (!pageIds.has(pageState.pageId)) {\n\t\t\t\tstore.remove([pageState.id])\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (pageState.croppingShapeId && !store.has(pageState.croppingShapeId)) {\n\t\t\t\tstore.put([{ ...pageState, croppingShapeId: null }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tif (pageState.focusedGroupId && !store.has(pageState.focusedGroupId)) {\n\t\t\t\tstore.put([{ ...pageState, focusedGroupId: null }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tif (pageState.hoveredShapeId && !store.has(pageState.hoveredShapeId)) {\n\t\t\t\tstore.put([{ ...pageState, hoveredShapeId: null }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tconst filteredSelectedIds = pageState.selectedShapeIds.filter((id) => store.has(id))\n\t\t\tif (filteredSelectedIds.length !== pageState.selectedShapeIds.length) {\n\t\t\t\tstore.put([{ ...pageState, selectedShapeIds: filteredSelectedIds }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tconst filteredHintingIds = pageState.hintingShapeIds.filter((id) => store.has(id))\n\t\t\tif (filteredHintingIds.length !== pageState.hintingShapeIds.length) {\n\t\t\t\tstore.put([{ ...pageState, hintingShapeIds: filteredHintingIds }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tconst filteredErasingIds = pageState.erasingShapeIds.filter((id) => store.has(id))\n\t\t\tif (filteredErasingIds.length !== pageState.erasingShapeIds.length) {\n\t\t\t\tstore.put([{ ...pageState, erasingShapeIds: filteredErasingIds }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ensureStoreIsUsable\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Signal } from '@tldraw/state'\nimport {\n\tSerializedStore,\n\tStore,\n\tStoreSchema,\n\tStoreSnapshot,\n\tStoreValidationFailure,\n} from '@tldraw/store'\nimport { IndexKey, JsonObject, annotateError, sortByIndex, structuredClone } from '@tldraw/utils'\nimport { TLAsset, TLAssetId } from './records/TLAsset'\nimport { CameraRecordType, TLCameraId } from './records/TLCamera'\nimport { DocumentRecordType, TLDOCUMENT_ID } from './records/TLDocument'\nimport { TLINSTANCE_ID } from './records/TLInstance'\nimport { PageRecordType, TLPageId } from './records/TLPage'\nimport { InstancePageStateRecordType, TLInstancePageStateId } from './records/TLPageState'\nimport { PointerRecordType, TLPOINTER_ID } from './records/TLPointer'\nimport { TLRecord } from './records/TLRecord'\n\n/**\n * Redacts the source of an asset record for error reporting.\n *\n * @param record - The asset record to redact\n * @returns The redacted record\n * @internal\n */\nexport function redactRecordForErrorReporting(record: any) {\n\tif (record.typeName === 'asset') {\n\t\tif ('src' in record) {\n\t\t\trecord.src = '<redacted>'\n\t\t}\n\n\t\tif ('src' in record.props) {\n\t\t\trecord.props.src = '<redacted>'\n\t\t}\n\t}\n}\n\n/**\n * The complete schema type for a tldraw store, defining the structure and validation rules\n * for all tldraw records and store properties.\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema } from '@tldraw/tlschema'\n *\n * const schema = createTLSchema()\n * const storeSchema: TLStoreSchema = schema\n * ```\n */\nexport type TLStoreSchema = StoreSchema<TLRecord, TLStoreProps>\n\n/**\n * A serialized representation of a tldraw store that can be persisted or transmitted.\n * Contains all store records in a JSON-serializable format.\n *\n * @public\n * @example\n * ```ts\n * // Serialize a store\n * const serializedStore: TLSerializedStore = store.serialize()\n *\n * // Save to localStorage\n * localStorage.setItem('drawing', JSON.stringify(serializedStore))\n * ```\n */\nexport type TLSerializedStore = SerializedStore<TLRecord>\n\n/**\n * A snapshot of a tldraw store at a specific point in time, containing all records\n * and metadata. Used for persistence, synchronization, and creating store backups.\n *\n * @public\n * @example\n * ```ts\n * // Create a snapshot\n * const snapshot: TLStoreSnapshot = store.getSnapshot()\n *\n * // Restore from snapshot\n * store.loadSnapshot(snapshot)\n * ```\n */\nexport type TLStoreSnapshot = StoreSnapshot<TLRecord>\n\n/**\n * Context information provided when resolving asset URLs, containing details about\n * the current rendering environment and user's connection to optimize asset delivery.\n *\n * @public\n * @example\n * ```ts\n * const assetStore: TLAssetStore = {\n * async resolve(asset, context: TLAssetContext) {\n * // Use low resolution for slow connections\n * if (context.networkEffectiveType === 'slow-2g') {\n * return `${asset.props.src}?quality=low`\n * }\n * // Use high DPI version for retina displays\n * if (context.dpr > 1) {\n * return `${asset.props.src}@2x`\n * }\n * return asset.props.src\n * }\n * }\n * ```\n */\nexport interface TLAssetContext {\n\t/**\n\t * The scale at which the asset is being rendered on-screen relative to its native dimensions.\n\t * If the asset is 1000px wide, but it's been resized/zoom so it takes 500px on-screen, this\n\t * will be 0.5.\n\t *\n\t * The scale measures CSS pixels, not device pixels.\n\t */\n\tscreenScale: number\n\t/** The {@link TLAssetContext.screenScale}, stepped to the nearest power-of-2 multiple. */\n\tsteppedScreenScale: number\n\t/** The device pixel ratio - how many CSS pixels are in one device pixel? */\n\tdpr: number\n\t/**\n\t * An alias for\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType | `navigator.connection.effectiveType` }\n\t * if it's available in the current browser. Use this to e.g. serve lower-resolution images to\n\t * users on slow connections.\n\t */\n\tnetworkEffectiveType: string | null\n\t/**\n\t * In some circumstances, we need to resolve a URL that points to the original version of a\n\t * particular asset. This is used when the asset will leave the current tldraw instance - e.g.\n\t * for copy/paste, or exports.\n\t */\n\tshouldResolveToOriginal: boolean\n}\n\n/**\n * Interface for storing and managing assets (images, videos, etc.) in tldraw.\n * Provides methods for uploading, resolving, and removing assets from storage.\n *\n * A `TLAssetStore` sits alongside the main {@link TLStore} and is responsible for storing and\n * retrieving large assets such as images. Generally, this should be part of a wider sync system:\n *\n * - By default, the store is in-memory only, so `TLAssetStore` converts images to data URLs\n * - When using\n * {@link @tldraw/editor#TldrawEditorWithoutStoreProps.persistenceKey | `persistenceKey`}, the\n * store is synced to the browser's local IndexedDB, so `TLAssetStore` stores images there too\n * - When using a multiplayer sync server, you would implement `TLAssetStore` to upload images to\n * e.g. an S3 bucket.\n *\n * @public\n * @example\n * ```ts\n * // Simple in-memory asset store\n * const assetStore: TLAssetStore = {\n * async upload(asset, file) {\n * const dataUrl = await fileToDataUrl(file)\n * return { src: dataUrl }\n * },\n *\n * async resolve(asset, context) {\n * return asset.props.src\n * },\n *\n * async remove(assetIds) {\n * // Clean up if needed\n * }\n * }\n * ```\n */\nexport interface TLAssetStore {\n\t/**\n\t * Upload an asset to your storage, returning a URL that can be used to refer to the asset\n\t * long-term.\n\t *\n\t * @param asset - Information & metadata about the asset being uploaded\n\t * @param file - The `File` to be uploaded\n\t * @returns A promise that resolves to the URL of the uploaded asset\n\t */\n\tupload(\n\t\tasset: TLAsset,\n\t\tfile: File,\n\t\tabortSignal?: AbortSignal\n\t): Promise<{ src: string; meta?: JsonObject }>\n\t/**\n\t * Resolve an asset to a URL. This is used when rendering the asset in the editor. By default,\n\t * this will just use `asset.props.src`, the URL returned by `upload()`. This can be used to\n\t * rewrite that URL to add access credentials, or optimized the asset for how it's currently\n\t * being displayed using the {@link TLAssetContext | information provided}.\n\t *\n\t * @param asset - the asset being resolved\n\t * @param ctx - information about the current environment and where the asset is being used\n\t * @returns The URL of the resolved asset, or `null` if the asset is not available\n\t */\n\tresolve?(asset: TLAsset, ctx: TLAssetContext): Promise<string | null> | string | null\n\t/**\n\t * Remove an asset from storage. This is called when the asset is no longer needed, e.g. when\n\t * the user deletes it from the editor.\n\t * @param asset - the asset being removed\n\t * @returns A promise that resolves when the asset has been removed\n\t */\n\tremove?(assetIds: TLAssetId[]): Promise<void>\n}\n\n/**\n * Configuration properties for a tldraw store, defining its behavior and integrations.\n * These props are passed when creating a new store instance.\n *\n * @public\n * @example\n * ```ts\n * const storeProps: TLStoreProps = {\n * defaultName: 'My Drawing',\n * assets: myAssetStore,\n * onMount: (editor) => {\n * console.log('Editor mounted')\n * return () => console.log('Editor unmounted')\n * },\n * collaboration: {\n * status: statusSignal,\n * mode: modeSignal\n * }\n * }\n *\n * const store = new Store({ schema, props: storeProps })\n * ```\n */\nexport interface TLStoreProps {\n\t/** Default name for new documents created in this store */\n\tdefaultName: string\n\t/** Asset store implementation for handling file uploads and storage */\n\tassets: Required<TLAssetStore>\n\t/**\n\t * Called when an {@link @tldraw/editor#Editor} connected to this store is mounted.\n\t * Can optionally return a cleanup function that will be called when unmounted.\n\t *\n\t * @param editor - The editor instance that was mounted\n\t * @returns Optional cleanup function\n\t */\n\tonMount(editor: unknown): void | (() => void)\n\t/** Optional collaboration configuration for multiplayer features */\n\tcollaboration?: {\n\t\t/** Signal indicating online/offline collaboration status */\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\t/** Signal indicating collaboration mode permissions */\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n}\n\n/**\n * The main tldraw store type, representing a reactive database of tldraw records\n * with associated store properties. This is the central data structure that holds\n * all shapes, assets, pages, and user state.\n *\n * @public\n * @example\n * ```ts\n * import { Store } from '@tldraw/store'\n * import { createTLSchema } from '@tldraw/tlschema'\n *\n * const schema = createTLSchema()\n * const store: TLStore = new Store({\n * schema,\n * props: {\n * defaultName: 'Untitled',\n * assets: myAssetStore,\n * onMount: () => console.log('Store mounted')\n * }\n * })\n * ```\n */\nexport type TLStore = Store<TLRecord, TLStoreProps>\n\n/**\n * Default validation failure handler for tldraw stores. This function is called\n * when a record fails validation during store operations. It annotates errors\n * with debugging information and determines whether to allow invalid records\n * during store initialization.\n *\n * @param options - The validation failure details\n * - error - The validation error that occurred\n * - phase - The store operation phase when validation failed\n * - record - The invalid record that caused the failure\n * - recordBefore - The previous state of the record (if applicable)\n * @returns The record to use (typically throws the annotated error)\n * @throws The original validation error with additional debugging context\n *\n * @public\n * @example\n * ```ts\n * const store = new Store({\n * schema,\n * props: storeProps,\n * onValidationFailure // Use this as the validation failure handler\n * })\n *\n * // The handler will be called automatically when validation fails\n * try {\n * store.put([invalidRecord])\n * } catch (error) {\n * // Error will contain debugging information added by onValidationFailure\n * }\n * ```\n */\nexport function onValidationFailure({\n\terror,\n\tphase,\n\trecord,\n\trecordBefore,\n}: StoreValidationFailure<TLRecord>): TLRecord {\n\tconst isExistingValidationIssue =\n\t\t// if we're initializing the store for the first time, we should\n\t\t// allow invalid records so people can load old buggy data:\n\t\tphase === 'initialize'\n\n\tannotateError(error, {\n\t\ttags: {\n\t\t\torigin: 'store.validateRecord',\n\t\t\tstorePhase: phase,\n\t\t\tisExistingValidationIssue,\n\t\t},\n\t\textras: {\n\t\t\trecordBefore: recordBefore\n\t\t\t\t? redactRecordForErrorReporting(structuredClone(recordBefore))\n\t\t\t\t: undefined,\n\t\t\trecordAfter: redactRecordForErrorReporting(structuredClone(record)),\n\t\t},\n\t})\n\n\tthrow error\n}\n\nfunction getDefaultPages() {\n\treturn [\n\t\tPageRecordType.create({\n\t\t\tid: 'page:page' as TLPageId,\n\t\t\tname: 'Page 1',\n\t\t\tindex: 'a1' as IndexKey,\n\t\t\tmeta: {},\n\t\t}),\n\t]\n}\n\n/**\n * Creates an integrity checker function that ensures the tldraw store maintains\n * a consistent and usable state. The checker validates that required records exist\n * and relationships between records are maintained.\n *\n * The integrity checker ensures:\n * - Document and pointer records exist\n * - At least one page exists\n * - Instance state references valid pages\n * - Page states and cameras exist for all pages\n * - Shape references in page states are valid\n *\n * @param store - The tldraw store to check for integrity\n * @returns A function that when called, validates and fixes store integrity\n *\n * @internal\n * @example\n * ```ts\n * const checker = createIntegrityChecker(store)\n *\n * // Run integrity check (typically called automatically)\n * checker()\n *\n * // The checker will create missing records and fix invalid references\n * ```\n */\nexport function createIntegrityChecker(store: Store<TLRecord, TLStoreProps>): () => void {\n\tconst $pageIds = store.query.ids('page')\n\tconst $pageStates = store.query.records('instance_page_state')\n\n\tconst ensureStoreIsUsable = (): void => {\n\t\t// make sure we have exactly one document\n\t\tif (!store.has(TLDOCUMENT_ID)) {\n\t\t\tstore.put([DocumentRecordType.create({ id: TLDOCUMENT_ID, name: store.props.defaultName })])\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\tif (!store.has(TLPOINTER_ID)) {\n\t\t\tstore.put([PointerRecordType.create({ id: TLPOINTER_ID })])\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\t// make sure there is at least one page\n\t\tconst pageIds = $pageIds.get()\n\t\tif (pageIds.size === 0) {\n\t\t\tstore.put(getDefaultPages())\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\tconst getFirstPageId = () => [...pageIds].map((id) => store.get(id)!).sort(sortByIndex)[0].id!\n\n\t\t// make sure we have state for the current user's current tab\n\t\tconst instanceState = store.get(TLINSTANCE_ID)\n\t\tif (!instanceState) {\n\t\t\tstore.put([\n\t\t\t\tstore.schema.types.instance.create({\n\t\t\t\t\tid: TLINSTANCE_ID,\n\t\t\t\t\tcurrentPageId: getFirstPageId(),\n\t\t\t\t\texportBackground: true,\n\t\t\t\t}),\n\t\t\t])\n\n\t\t\treturn ensureStoreIsUsable()\n\t\t} else if (!pageIds.has(instanceState.currentPageId)) {\n\t\t\tstore.put([{ ...instanceState, currentPageId: getFirstPageId() }])\n\t\t\treturn ensureStoreIsUsable()\n\t\t}\n\n\t\t// make sure we have page states and cameras for all the pages\n\t\tconst missingPageStateIds = new Set<TLInstancePageStateId>()\n\t\tconst missingCameraIds = new Set<TLCameraId>()\n\t\tfor (const id of pageIds) {\n\t\t\tconst pageStateId = InstancePageStateRecordType.createId(id)\n\t\t\tconst pageState = store.get(pageStateId)\n\t\t\tif (!pageState) {\n\t\t\t\tmissingPageStateIds.add(pageStateId)\n\t\t\t}\n\t\t\tconst cameraId = CameraRecordType.createId(id)\n\t\t\tif (!store.has(cameraId)) {\n\t\t\t\tmissingCameraIds.add(cameraId)\n\t\t\t}\n\t\t}\n\n\t\tif (missingPageStateIds.size > 0) {\n\t\t\tstore.put(\n\t\t\t\t[...missingPageStateIds].map((id) =>\n\t\t\t\t\tInstancePageStateRecordType.create({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tpageId: InstancePageStateRecordType.parseId(id) as TLPageId,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\n\t\tif (missingCameraIds.size > 0) {\n\t\t\tstore.put([...missingCameraIds].map((id) => CameraRecordType.create({ id })))\n\t\t}\n\n\t\tconst pageStates = $pageStates.get()\n\t\tfor (const pageState of pageStates) {\n\t\t\tif (!pageIds.has(pageState.pageId)) {\n\t\t\t\tstore.remove([pageState.id])\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (pageState.croppingShapeId && !store.has(pageState.croppingShapeId)) {\n\t\t\t\tstore.put([{ ...pageState, croppingShapeId: null }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tif (pageState.focusedGroupId && !store.has(pageState.focusedGroupId)) {\n\t\t\t\tstore.put([{ ...pageState, focusedGroupId: null }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tif (pageState.hoveredShapeId && !store.has(pageState.hoveredShapeId)) {\n\t\t\t\tstore.put([{ ...pageState, hoveredShapeId: null }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tconst filteredSelectedIds = pageState.selectedShapeIds.filter((id) => store.has(id))\n\t\t\tif (filteredSelectedIds.length !== pageState.selectedShapeIds.length) {\n\t\t\t\tstore.put([{ ...pageState, selectedShapeIds: filteredSelectedIds }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tconst filteredHintingIds = pageState.hintingShapeIds.filter((id) => store.has(id))\n\t\t\tif (filteredHintingIds.length !== pageState.hintingShapeIds.length) {\n\t\t\t\tstore.put([{ ...pageState, hintingShapeIds: filteredHintingIds }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t\tconst filteredErasingIds = pageState.erasingShapeIds.filter((id) => store.has(id))\n\t\t\tif (filteredErasingIds.length !== pageState.erasingShapeIds.length) {\n\t\t\t\tstore.put([{ ...pageState, erasingShapeIds: filteredErasingIds }])\n\t\t\t\treturn ensureStoreIsUsable()\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ensureStoreIsUsable\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/assets/TLBaseAsset.ts"],
4
- "sourcesContent": ["import { BaseRecord } from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { TLAssetId } from '../records/TLAsset'\n\n/** @public */\nexport interface TLBaseAsset<Type extends string, Props> extends BaseRecord<'asset', TLAssetId> {\n\ttype: Type\n\tprops: Props\n\tmeta: JsonObject\n}\n\n/**\n * A validator for asset record type Ids.\n *\n * @public */\nexport const assetIdValidator = idValidator<TLAssetId>('asset')\n\n/**\n * Create a validator for an asset record type.\n *\n * @param type - The type of the asset\n * @param props - The validator for the asset's props\n *\n * @public */\nexport function createAssetValidator<Type extends string, Props extends JsonObject>(\n\ttype: Type,\n\tprops: T.Validator<Props>\n) {\n\treturn T.object<{\n\t\tid: TLAssetId\n\t\ttypeName: 'asset'\n\t\ttype: Type\n\t\tprops: Props\n\t\tmeta: JsonObject\n\t}>({\n\t\tid: assetIdValidator,\n\t\ttypeName: T.literal('asset'),\n\t\ttype: T.literal(type),\n\t\tprops,\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAAkB;AAClB,0BAA4B;AAcrB,MAAM,uBAAmB,iCAAuB,OAAO;AASvD,SAAS,qBACf,MACA,OACC;AACD,SAAO,kBAAE,OAMN;AAAA,IACF,IAAI;AAAA,IACJ,UAAU,kBAAE,QAAQ,OAAO;AAAA,IAC3B,MAAM,kBAAE,QAAQ,IAAI;AAAA,IACpB;AAAA,IACA,MAAM,kBAAE;AAAA,EACT,CAAC;AACF;",
4
+ "sourcesContent": ["import { BaseRecord } from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { TLAssetId } from '../records/TLAsset'\n\n/**\n * Base interface for all asset records in tldraw. Assets represent external resources\n * like images, videos, or bookmarks that shapes can reference. This interface extends\n * the base record system with asset-specific typing.\n *\n * @param Type - The specific asset type identifier (e.g., 'image', 'video', 'bookmark')\n * @param Props - The properties object specific to this asset type\n *\n * @example\n * ```ts\n * // Define a custom asset type\n * interface MyCustomAsset extends TLBaseAsset<'custom', { url: string; title: string }> {}\n *\n * const customAsset: MyCustomAsset = {\n * id: 'asset:custom123',\n * typeName: 'asset',\n * type: 'custom',\n * props: {\n * url: 'https://example.com',\n * title: 'My Custom Asset'\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport interface TLBaseAsset<Type extends string, Props> extends BaseRecord<'asset', TLAssetId> {\n\t/** The specific type of this asset (e.g., 'image', 'video', 'bookmark') */\n\ttype: Type\n\t/** Type-specific properties for this asset */\n\tprops: Props\n\t/** User-defined metadata that can be attached to this asset */\n\tmeta: JsonObject\n}\n\n/**\n * A validator for asset record type IDs. This validator ensures that asset IDs\n * follow the correct format and type structure required by tldraw's asset system.\n * Asset IDs are prefixed with 'asset:' followed by a unique identifier.\n *\n * @example\n * ```ts\n * import { assetIdValidator } from '@tldraw/tlschema'\n *\n * // Valid asset ID\n * const validId = 'asset:abc123'\n * console.log(assetIdValidator.isValid(validId)) // true\n *\n * // Invalid asset ID\n * const invalidId = 'shape:abc123'\n * console.log(assetIdValidator.isValid(invalidId)) // false\n * ```\n *\n * @public\n */\nexport const assetIdValidator = idValidator<TLAssetId>('asset')\n\n/**\n * Creates a validator for a specific asset record type. This factory function generates\n * a complete validator that validates the entire asset record structure including the\n * base properties (id, typeName, type, meta) and the type-specific props.\n *\n * @param type - The asset type identifier (e.g., 'image', 'video', 'bookmark')\n * @param props - The validator for the asset's type-specific properties\n * @returns A complete validator for the asset record type\n *\n * @example\n * ```ts\n * import { createAssetValidator, TLBaseAsset } from '@tldraw/tlschema'\n * import { T } from '@tldraw/validate'\n *\n * // Define a custom asset type\n * type TLCustomAsset = TLBaseAsset<'custom', {\n * url: string\n * title: string\n * description?: string\n * }>\n *\n * // Create validator for the custom asset\n * const customAssetValidator = createAssetValidator('custom', T.object({\n * url: T.string,\n * title: T.string,\n * description: T.string.optional()\n * }))\n *\n * // Use the validator\n * const assetData = {\n * id: 'asset:custom123',\n * typeName: 'asset' as const,\n * type: 'custom' as const,\n * props: {\n * url: 'https://example.com',\n * title: 'My Custom Asset'\n * },\n * meta: {}\n * }\n *\n * const validatedAsset = customAssetValidator.validate(assetData)\n * ```\n *\n * @public\n */\nexport function createAssetValidator<Type extends string, Props extends JsonObject>(\n\ttype: Type,\n\tprops: T.Validator<Props>\n) {\n\treturn T.object<{\n\t\tid: TLAssetId\n\t\ttypeName: 'asset'\n\t\ttype: Type\n\t\tprops: Props\n\t\tmeta: JsonObject\n\t}>({\n\t\tid: assetIdValidator,\n\t\ttypeName: T.literal('asset'),\n\t\ttype: T.literal(type),\n\t\tprops,\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAAkB;AAClB,0BAA4B;AA2DrB,MAAM,uBAAmB,iCAAuB,OAAO;AA+CvD,SAAS,qBACf,MACA,OACC;AACD,SAAO,kBAAE,OAMN;AAAA,IACF,IAAI;AAAA,IACJ,UAAU,kBAAE,QAAQ,OAAO;AAAA,IAC3B,MAAM,kBAAE,QAAQ,IAAI;AAAA,IACpB;AAAA,IACA,MAAM,kBAAE;AAAA,EACT,CAAC;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/assets/TLBookmarkAsset.ts"],
4
- "sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLAsset } from '../records/TLAsset'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset used for URL bookmarks, used by the TLBookmarkShape.\n *\n * @public */\nexport type TLBookmarkAsset = TLBaseAsset<\n\t'bookmark',\n\t{\n\t\ttitle: string\n\t\tdescription: string\n\t\timage: string\n\t\tfavicon: string\n\t\tsrc: string | null\n\t}\n>\n\n/** @public */\nexport const bookmarkAssetValidator: T.Validator<TLBookmarkAsset> = createAssetValidator(\n\t'bookmark',\n\tT.object({\n\t\ttitle: T.string,\n\t\tdescription: T.string,\n\t\timage: T.string,\n\t\tfavicon: T.string,\n\t\tsrc: T.srcUrl.nullable(),\n\t})\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.bookmark', {\n\tMakeUrlsValid: 1,\n\tAddFavicon: 2,\n} as const)\n\nexport { Versions as bookmarkAssetVersions }\n\n/** @public */\nexport const bookmarkAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.bookmark',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLAsset).type === 'bookmark',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFavicon,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.favicon)) {\n\t\t\t\t\tasset.props.favicon = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.favicon\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;AAClE,sBAAkB;AAElB,yBAAkD;AAkB3C,MAAM,6BAAuD;AAAA,EACnE;AAAA,EACA,kBAAE,OAAO;AAAA,IACR,OAAO,kBAAE;AAAA,IACT,aAAa,kBAAE;AAAA,IACf,OAAO,kBAAE;AAAA,IACT,SAAS,kBAAE;AAAA,IACX,KAAK,kBAAE,OAAO,SAAS;AAAA,EACxB,CAAC;AACF;AAEA,MAAM,eAAW,iCAAmB,6BAA6B;AAAA,EAChE,eAAe;AAAA,EACf,YAAY;AACb,CAAU;AAKH,MAAM,8BAA0B,4CAA8B;AAAA,EACpE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAkB,SAAS;AAAA,EAC/C,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,OAAO,GAAG;AAC3C,gBAAM,MAAM,UAAU;AAAA,QACvB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
4
+ "sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLAsset } from '../records/TLAsset'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset used for URL bookmarks, used by the TLBookmarkShape.\n *\n * @public */\nexport type TLBookmarkAsset = TLBaseAsset<\n\t'bookmark',\n\t{\n\t\ttitle: string\n\t\tdescription: string\n\t\timage: string\n\t\tfavicon: string\n\t\tsrc: string | null\n\t}\n>\n\n/**\n * Validator for TLBookmarkAsset records. Validates the structure and data types\n * of bookmark asset properties including title, description, image, favicon, and source URL.\n *\n * @example\n * ```ts\n * const bookmarkData = {\n * id: 'asset:bookmark1',\n * typeName: 'asset',\n * type: 'bookmark',\n * props: {\n * title: 'Example Website',\n * description: 'A great example site',\n * image: 'https://example.com/preview.jpg',\n * favicon: 'https://example.com/favicon.ico',\n * src: 'https://example.com'\n * }\n * }\n *\n * const isValid = bookmarkAssetValidator.isValid(bookmarkData)\n * ```\n *\n * @public\n */\nexport const bookmarkAssetValidator: T.Validator<TLBookmarkAsset> = createAssetValidator(\n\t'bookmark',\n\tT.object({\n\t\ttitle: T.string,\n\t\tdescription: T.string,\n\t\timage: T.string,\n\t\tfavicon: T.string,\n\t\tsrc: T.srcUrl.nullable(),\n\t})\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.bookmark', {\n\tMakeUrlsValid: 1,\n\tAddFavicon: 2,\n} as const)\n\n/**\n * Migration version identifiers for bookmark assets. These versions track\n * the evolution of the bookmark asset schema over time.\n *\n * Available versions:\n * - `MakeUrlsValid` (v1): Ensures src URLs are valid or empty\n * - `AddFavicon` (v2): Adds favicon property to bookmark assets\n *\n * @example\n * ```ts\n * import { bookmarkAssetVersions } from '@tldraw/tlschema'\n *\n * // Check if a migration exists\n * console.log(bookmarkAssetVersions.AddFavicon) // 2\n * ```\n *\n * @public\n */\nexport { Versions as bookmarkAssetVersions }\n\n/**\n * Migration sequence for bookmark assets. Handles the evolution of bookmark asset\n * data structure over time, ensuring backward and forward compatibility.\n *\n * The migration sequence includes:\n * 1. **MakeUrlsValid** (v1): Validates and cleans up src URLs, setting invalid URLs to empty string\n * 2. **AddFavicon** (v2): Adds the favicon property and validates it, setting invalid favicons to empty string\n *\n * @public\n */\nexport const bookmarkAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.bookmark',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLAsset).type === 'bookmark',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFavicon,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.favicon)) {\n\t\t\t\t\tasset.props.favicon = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.favicon\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;AAClE,sBAAkB;AAElB,yBAAkD;AAyC3C,MAAM,6BAAuD;AAAA,EACnE;AAAA,EACA,kBAAE,OAAO;AAAA,IACR,OAAO,kBAAE;AAAA,IACT,aAAa,kBAAE;AAAA,IACf,OAAO,kBAAE;AAAA,IACT,SAAS,kBAAE;AAAA,IACX,KAAK,kBAAE,OAAO,SAAS;AAAA,EACxB,CAAC;AACF;AAEA,MAAM,eAAW,iCAAmB,6BAA6B;AAAA,EAChE,eAAe;AAAA,EACf,YAAY;AACb,CAAU;AAgCH,MAAM,8BAA0B,4CAA8B;AAAA,EACpE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAkB,SAAS;AAAA,EAC/C,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,OAAO,GAAG;AAC3C,gBAAM,MAAM,UAAU;AAAA,QACvB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/assets/TLImageAsset.ts"],
4
- "sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLAsset } from '../records/TLAsset'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset for images such as PNGs and JPEGs, used by the TLImageShape.\n *\n * @public */\nexport type TLImageAsset = TLBaseAsset<\n\t'image',\n\t{\n\t\tw: number\n\t\th: number\n\t\tname: string\n\t\tisAnimated: boolean\n\t\tmimeType: string | null\n\t\tsrc: string | null\n\t\tfileSize?: number\n\t}\n>\n\n/** @public */\nexport const imageAssetValidator: T.Validator<TLImageAsset> = createAssetValidator(\n\t'image',\n\tT.object({\n\t\tw: T.number,\n\t\th: T.number,\n\t\tname: T.string,\n\t\tisAnimated: T.boolean,\n\t\tmimeType: T.string.nullable(),\n\t\tsrc: T.srcUrl.nullable(),\n\t\tfileSize: T.nonZeroNumber.optional(),\n\t})\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.image', {\n\tAddIsAnimated: 1,\n\tRenameWidthHeight: 2,\n\tMakeUrlsValid: 3,\n\tAddFileSize: 4,\n\tMakeFileSizeOptional: 5,\n} as const)\n\nexport { Versions as imageAssetVersions }\n\n/** @public */\nexport const imageAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.image',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLAsset).type === 'image',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.AddIsAnimated,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.isAnimated = false\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.isAnimated\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.RenameWidthHeight,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.w = asset.props.width\n\t\t\t\tasset.props.h = asset.props.height\n\t\t\t\tdelete asset.props.width\n\t\t\t\tdelete asset.props.height\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tasset.props.width = asset.props.w\n\t\t\t\tasset.props.height = asset.props.h\n\t\t\t\tdelete asset.props.w\n\t\t\t\tdelete asset.props.h\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFileSize,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.fileSize = -1\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.fileSize\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeFileSizeOptional,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === -1) {\n\t\t\t\t\tasset.props.fileSize = undefined\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === undefined) {\n\t\t\t\t\tasset.props.fileSize = -1\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;AAClE,sBAAkB;AAElB,yBAAkD;AAoB3C,MAAM,0BAAiD;AAAA,EAC7D;AAAA,EACA,kBAAE,OAAO;AAAA,IACR,GAAG,kBAAE;AAAA,IACL,GAAG,kBAAE;AAAA,IACL,MAAM,kBAAE;AAAA,IACR,YAAY,kBAAE;AAAA,IACd,UAAU,kBAAE,OAAO,SAAS;AAAA,IAC5B,KAAK,kBAAE,OAAO,SAAS;AAAA,IACvB,UAAU,kBAAE,cAAc,SAAS;AAAA,EACpC,CAAC;AACF;AAEA,MAAM,eAAW,iCAAmB,0BAA0B;AAAA,EAC7D,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,sBAAsB;AACvB,CAAU;AAKH,MAAM,2BAAuB,4CAA8B;AAAA,EACjE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAkB,SAAS;AAAA,EAC/C,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,aAAa;AAAA,MAC1B;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,cAAM,MAAM,QAAQ,MAAM,MAAM;AAChC,cAAM,MAAM,SAAS,MAAM,MAAM;AACjC,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,WAAW;AAAA,MACxB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,MAAM,MAAM,aAAa,IAAI;AAChC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,YAAI,MAAM,MAAM,aAAa,QAAW;AACvC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
4
+ "sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLAsset } from '../records/TLAsset'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset for images such as PNGs and JPEGs, used by the TLImageShape.\n *\n * @public */\nexport type TLImageAsset = TLBaseAsset<\n\t'image',\n\t{\n\t\tw: number\n\t\th: number\n\t\tname: string\n\t\tisAnimated: boolean\n\t\tmimeType: string | null\n\t\tsrc: string | null\n\t\tfileSize?: number\n\t}\n>\n\n/**\n * Validator for image assets. Validates the structure and properties of TLImageAsset records\n * to ensure data integrity when image assets are stored or retrieved from the tldraw store.\n *\n * @example\n * ```ts\n * import { imageAssetValidator } from '@tldraw/tlschema'\n *\n * const imageAsset = {\n * id: 'asset:image123',\n * typeName: 'asset',\n * type: 'image',\n * props: {\n * w: 800,\n * h: 600,\n * name: 'photo.jpg',\n * isAnimated: false,\n * mimeType: 'image/jpeg',\n * src: 'https://example.com/photo.jpg',\n * fileSize: 156000\n * },\n * meta: {}\n * }\n *\n * // Validate the asset\n * const isValid = imageAssetValidator.validate(imageAsset)\n * ```\n *\n * @public\n */\nexport const imageAssetValidator: T.Validator<TLImageAsset> = createAssetValidator(\n\t'image',\n\tT.object({\n\t\tw: T.number,\n\t\th: T.number,\n\t\tname: T.string,\n\t\tisAnimated: T.boolean,\n\t\tmimeType: T.string.nullable(),\n\t\tsrc: T.srcUrl.nullable(),\n\t\tfileSize: T.nonZeroNumber.optional(),\n\t})\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.image', {\n\tAddIsAnimated: 1,\n\tRenameWidthHeight: 2,\n\tMakeUrlsValid: 3,\n\tAddFileSize: 4,\n\tMakeFileSizeOptional: 5,\n} as const)\n\n/**\n * Migration version identifiers for image assets. These define the different schema versions\n * that image assets have gone through during the evolution of the tldraw data model.\n *\n * @example\n * ```ts\n * import { imageAssetVersions } from '@tldraw/tlschema'\n *\n * // Access specific version IDs\n * console.log(imageAssetVersions.AddIsAnimated) // Version when isAnimated was added\n * console.log(imageAssetVersions.RenameWidthHeight) // Version when width/height became w/h\n * ```\n *\n * @public\n */\nexport { Versions as imageAssetVersions }\n\n/**\n * Migration sequence for image assets. Handles the evolution of the image asset schema\n * over time, providing both forward (up) and backward (down) migration functions to\n * maintain compatibility across different versions of the tldraw data model.\n *\n * The sequence includes migrations for:\n * - Adding the `isAnimated` property to track animated images\n * - Renaming `width`/`height` properties to shorter `w`/`h` names\n * - Ensuring URLs are valid format\n * - Adding file size tracking\n * - Making file size optional\n *\n *\n * @public\n */\nexport const imageAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.image',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLAsset).type === 'image',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.AddIsAnimated,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.isAnimated = false\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.isAnimated\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.RenameWidthHeight,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.w = asset.props.width\n\t\t\t\tasset.props.h = asset.props.height\n\t\t\t\tdelete asset.props.width\n\t\t\t\tdelete asset.props.height\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tasset.props.width = asset.props.w\n\t\t\t\tasset.props.height = asset.props.h\n\t\t\t\tdelete asset.props.w\n\t\t\t\tdelete asset.props.h\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFileSize,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.fileSize = -1\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.fileSize\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeFileSizeOptional,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === -1) {\n\t\t\t\t\tasset.props.fileSize = undefined\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === undefined) {\n\t\t\t\t\tasset.props.fileSize = -1\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;AAClE,sBAAkB;AAElB,yBAAkD;AAiD3C,MAAM,0BAAiD;AAAA,EAC7D;AAAA,EACA,kBAAE,OAAO;AAAA,IACR,GAAG,kBAAE;AAAA,IACL,GAAG,kBAAE;AAAA,IACL,MAAM,kBAAE;AAAA,IACR,YAAY,kBAAE;AAAA,IACd,UAAU,kBAAE,OAAO,SAAS;AAAA,IAC5B,KAAK,kBAAE,OAAO,SAAS;AAAA,IACvB,UAAU,kBAAE,cAAc,SAAS;AAAA,EACpC,CAAC;AACF;AAEA,MAAM,eAAW,iCAAmB,0BAA0B;AAAA,EAC7D,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,sBAAsB;AACvB,CAAU;AAkCH,MAAM,2BAAuB,4CAA8B;AAAA,EACjE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAkB,SAAS;AAAA,EAC/C,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,aAAa;AAAA,MAC1B;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,cAAM,MAAM,QAAQ,MAAM,MAAM;AAChC,cAAM,MAAM,SAAS,MAAM,MAAM;AACjC,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,WAAW;AAAA,MACxB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,MAAM,MAAM,aAAa,IAAI;AAChC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,YAAI,MAAM,MAAM,aAAa,QAAW;AACvC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/assets/TLVideoAsset.ts"],
4
- "sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLAsset } from '../records/TLAsset'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset used for videos, used by the TLVideoShape.\n *\n * @public */\nexport type TLVideoAsset = TLBaseAsset<\n\t'video',\n\t{\n\t\tw: number\n\t\th: number\n\t\tname: string\n\t\tisAnimated: boolean\n\t\tmimeType: string | null\n\t\tsrc: string | null\n\t\tfileSize?: number\n\t}\n>\n\n/** @public */\nexport const videoAssetValidator: T.Validator<TLVideoAsset> = createAssetValidator(\n\t'video',\n\tT.object({\n\t\tw: T.number,\n\t\th: T.number,\n\t\tname: T.string,\n\t\tisAnimated: T.boolean,\n\t\tmimeType: T.string.nullable(),\n\t\tsrc: T.srcUrl.nullable(),\n\t\tfileSize: T.number.optional(),\n\t})\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.video', {\n\tAddIsAnimated: 1,\n\tRenameWidthHeight: 2,\n\tMakeUrlsValid: 3,\n\tAddFileSize: 4,\n\tMakeFileSizeOptional: 5,\n} as const)\n\nexport { Versions as videoAssetVersions }\n\n/** @public */\nexport const videoAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.video',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLAsset).type === 'video',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.AddIsAnimated,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.isAnimated = false\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.isAnimated\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.RenameWidthHeight,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.w = asset.props.width\n\t\t\t\tasset.props.h = asset.props.height\n\t\t\t\tdelete asset.props.width\n\t\t\t\tdelete asset.props.height\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tasset.props.width = asset.props.w\n\t\t\t\tasset.props.height = asset.props.h\n\t\t\t\tdelete asset.props.w\n\t\t\t\tdelete asset.props.h\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFileSize,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.fileSize = -1\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.fileSize\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeFileSizeOptional,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === -1) {\n\t\t\t\t\tasset.props.fileSize = undefined\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === undefined) {\n\t\t\t\t\tasset.props.fileSize = -1\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;AAClE,sBAAkB;AAElB,yBAAkD;AAoB3C,MAAM,0BAAiD;AAAA,EAC7D;AAAA,EACA,kBAAE,OAAO;AAAA,IACR,GAAG,kBAAE;AAAA,IACL,GAAG,kBAAE;AAAA,IACL,MAAM,kBAAE;AAAA,IACR,YAAY,kBAAE;AAAA,IACd,UAAU,kBAAE,OAAO,SAAS;AAAA,IAC5B,KAAK,kBAAE,OAAO,SAAS;AAAA,IACvB,UAAU,kBAAE,OAAO,SAAS;AAAA,EAC7B,CAAC;AACF;AAEA,MAAM,eAAW,iCAAmB,0BAA0B;AAAA,EAC7D,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,sBAAsB;AACvB,CAAU;AAKH,MAAM,2BAAuB,4CAA8B;AAAA,EACjE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAkB,SAAS;AAAA,EAC/C,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,aAAa;AAAA,MAC1B;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,cAAM,MAAM,QAAQ,MAAM,MAAM;AAChC,cAAM,MAAM,SAAS,MAAM,MAAM;AACjC,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,WAAW;AAAA,MACxB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,MAAM,MAAM,aAAa,IAAI;AAChC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,YAAI,MAAM,MAAM,aAAa,QAAW;AACvC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
4
+ "sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLAsset } from '../records/TLAsset'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset record representing video files that can be displayed in video shapes.\n * Video assets store metadata about video files including dimensions, MIME type,\n * animation status, and file source information. They are referenced by TLVideoShape\n * instances to display video content on the canvas.\n *\n * @example\n * ```ts\n * import { TLVideoAsset } from '@tldraw/tlschema'\n *\n * const videoAsset: TLVideoAsset = {\n * id: 'asset:video123',\n * typeName: 'asset',\n * type: 'video',\n * props: {\n * w: 1920,\n * h: 1080,\n * name: 'my-video.mp4',\n * isAnimated: true,\n * mimeType: 'video/mp4',\n * src: 'https://example.com/video.mp4',\n * fileSize: 5242880\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport type TLVideoAsset = TLBaseAsset<\n\t'video',\n\t{\n\t\t/** The width of the video in pixels */\n\t\tw: number\n\t\t/** The height of the video in pixels */\n\t\th: number\n\t\t/** The original filename or display name of the video */\n\t\tname: string\n\t\t/** Whether the video contains animation/motion (true for most videos) */\n\t\tisAnimated: boolean\n\t\t/** The MIME type of the video file (e.g., 'video/mp4', 'video/webm'), null if unknown */\n\t\tmimeType: string | null\n\t\t/** The source URL or data URI for the video file, null if not yet available */\n\t\tsrc: string | null\n\t\t/** The file size in bytes, optional for backward compatibility */\n\t\tfileSize?: number\n\t}\n>\n\n/**\n * Runtime validator for TLVideoAsset records. This validator ensures that video asset\n * data conforms to the expected structure and types, providing type safety at runtime.\n * It validates dimensions, file metadata, and ensures URLs are properly formatted.\n *\n * @example\n * ```ts\n * import { videoAssetValidator } from '@tldraw/tlschema'\n *\n * // Validate a video asset object\n * const validAsset = videoAssetValidator.validate({\n * id: 'asset:video123',\n * typeName: 'asset',\n * type: 'video',\n * props: {\n * w: 1920,\n * h: 1080,\n * name: 'video.mp4',\n * isAnimated: true,\n * mimeType: 'video/mp4',\n * src: 'https://example.com/video.mp4',\n * fileSize: 1024000\n * },\n * meta: {}\n * })\n * ```\n *\n * @public\n */\nexport const videoAssetValidator: T.Validator<TLVideoAsset> = createAssetValidator(\n\t'video',\n\tT.object({\n\t\tw: T.number,\n\t\th: T.number,\n\t\tname: T.string,\n\t\tisAnimated: T.boolean,\n\t\tmimeType: T.string.nullable(),\n\t\tsrc: T.srcUrl.nullable(),\n\t\tfileSize: T.number.optional(),\n\t})\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.video', {\n\tAddIsAnimated: 1,\n\tRenameWidthHeight: 2,\n\tMakeUrlsValid: 3,\n\tAddFileSize: 4,\n\tMakeFileSizeOptional: 5,\n} as const)\n\n/**\n * Version identifiers for video asset migration sequences. These versions track\n * the evolution of the video asset schema over time, enabling proper data migration\n * when the asset structure changes.\n *\n * @example\n * ```ts\n * import { videoAssetVersions } from '@tldraw/tlschema'\n *\n * // Check the current version of a specific migration\n * console.log(videoAssetVersions.AddFileSize) // 4\n * ```\n *\n * @public\n */\nexport { Versions as videoAssetVersions }\n\n/**\n * Migration sequence for video assets that handles schema evolution over time.\n * This sequence defines how video asset data should be transformed when upgrading\n * or downgrading between different schema versions. Each migration step handles\n * specific changes like adding properties, renaming fields, or changing data formats.\n *\n * The migrations handle:\n * - Adding animation detection (isAnimated property)\n * - Renaming width/height properties to w/h for consistency\n * - Ensuring URL validity for src properties\n * - Adding file size tracking\n * - Making file size optional for backward compatibility\n *\n * @public\n */\nexport const videoAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.video',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLAsset).type === 'video',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.AddIsAnimated,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.isAnimated = false\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.isAnimated\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.RenameWidthHeight,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.w = asset.props.width\n\t\t\t\tasset.props.h = asset.props.height\n\t\t\t\tdelete asset.props.width\n\t\t\t\tdelete asset.props.height\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tasset.props.width = asset.props.w\n\t\t\t\tasset.props.height = asset.props.h\n\t\t\t\tdelete asset.props.w\n\t\t\t\tdelete asset.props.h\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFileSize,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.fileSize = -1\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.fileSize\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeFileSizeOptional,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === -1) {\n\t\t\t\t\tasset.props.fileSize = undefined\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === undefined) {\n\t\t\t\t\tasset.props.fileSize = -1\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;AAClE,sBAAkB;AAElB,yBAAkD;AAgF3C,MAAM,0BAAiD;AAAA,EAC7D;AAAA,EACA,kBAAE,OAAO;AAAA,IACR,GAAG,kBAAE;AAAA,IACL,GAAG,kBAAE;AAAA,IACL,MAAM,kBAAE;AAAA,IACR,YAAY,kBAAE;AAAA,IACd,UAAU,kBAAE,OAAO,SAAS;AAAA,IAC5B,KAAK,kBAAE,OAAO,SAAS;AAAA,IACvB,UAAU,kBAAE,OAAO,SAAS;AAAA,EAC7B,CAAC;AACF;AAEA,MAAM,eAAW,iCAAmB,0BAA0B;AAAA,EAC7D,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,sBAAsB;AACvB,CAAU;AAkCH,MAAM,2BAAuB,4CAA8B;AAAA,EACjE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAkB,SAAS;AAAA,EAC/C,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,aAAa;AAAA,MAC1B;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,cAAM,MAAM,QAAQ,MAAM,MAAM;AAChC,cAAM,MAAM,SAAS,MAAM,MAAM;AACjC,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,kBAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,WAAW;AAAA,MACxB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,MAAM,MAAM,aAAa,IAAI;AAChC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,YAAI,MAAM,MAAM,aAAa,QAAW;AACvC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/bindings/TLArrowBinding.ts"],
4
- "sourcesContent": ["import { T } from '@tldraw/validate'\nimport { VecModel, vecModelValidator } from '../misc/geometry-types'\nimport {\n\tcreateBindingPropsMigrationIds,\n\tcreateBindingPropsMigrationSequence,\n} from '../records/TLBinding'\nimport { RecordProps } from '../recordsWithProps'\nimport { arrowShapeVersions } from '../shapes/TLArrowShape'\nimport { TLBaseBinding } from './TLBaseBinding'\n\n/** @public */\nexport const ElbowArrowSnap = T.literalEnum('center', 'edge-point', 'edge', 'none')\n/** @public */\nexport type ElbowArrowSnap = T.TypeOf<typeof ElbowArrowSnap>\n\n/** @public */\nexport interface TLArrowBindingProps {\n\tterminal: 'start' | 'end'\n\tnormalizedAnchor: VecModel\n\t/**\n\t * exact is whether the arrow head 'enters' the bound shape to point directly at the binding\n\t * anchor point\n\t */\n\tisExact: boolean\n\t/**\n\t * precise is whether to bind to the normalizedAnchor, or to the middle of the shape\n\t */\n\tisPrecise: boolean\n\tsnap: ElbowArrowSnap\n}\n\n/** @public */\nexport const arrowBindingProps: RecordProps<TLArrowBinding> = {\n\tterminal: T.literalEnum('start', 'end'),\n\tnormalizedAnchor: vecModelValidator,\n\tisExact: T.boolean,\n\tisPrecise: T.boolean,\n\tsnap: ElbowArrowSnap,\n}\n\n/** @public */\nexport type TLArrowBinding = TLBaseBinding<'arrow', TLArrowBindingProps>\n\n/** @public */\nexport const arrowBindingVersions = createBindingPropsMigrationIds('arrow', {\n\tAddSnap: 1,\n})\n\n/** @public */\nexport const arrowBindingMigrations = createBindingPropsMigrationSequence({\n\tsequence: [\n\t\t{ dependsOn: [arrowShapeVersions.ExtractBindings] },\n\t\t{\n\t\t\tid: arrowBindingVersions.AddSnap,\n\t\t\tup: (props) => {\n\t\t\t\tprops.snap = 'none'\n\t\t\t},\n\t\t\tdown: (props) => {\n\t\t\t\tdelete props.snap\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAkB;AAClB,4BAA4C;AAC5C,uBAGO;AAEP,0BAAmC;AAI5B,MAAM,iBAAiB,kBAAE,YAAY,UAAU,cAAc,QAAQ,MAAM;AAqB3E,MAAM,oBAAiD;AAAA,EAC7D,UAAU,kBAAE,YAAY,SAAS,KAAK;AAAA,EACtC,kBAAkB;AAAA,EAClB,SAAS,kBAAE;AAAA,EACX,WAAW,kBAAE;AAAA,EACb,MAAM;AACP;AAMO,MAAM,2BAAuB,iDAA+B,SAAS;AAAA,EAC3E,SAAS;AACV,CAAC;AAGM,MAAM,6BAAyB,sDAAoC;AAAA,EACzE,UAAU;AAAA,IACT,EAAE,WAAW,CAAC,uCAAmB,eAAe,EAAE;AAAA,IAClD;AAAA,MACC,IAAI,qBAAqB;AAAA,MACzB,IAAI,CAAC,UAAU;AACd,cAAM,OAAO;AAAA,MACd;AAAA,MACA,MAAM,CAAC,UAAU;AAChB,eAAO,MAAM;AAAA,MACd;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
4
+ "sourcesContent": ["import { T } from '@tldraw/validate'\nimport { VecModel, vecModelValidator } from '../misc/geometry-types'\nimport {\n\tcreateBindingPropsMigrationIds,\n\tcreateBindingPropsMigrationSequence,\n} from '../records/TLBinding'\nimport { RecordProps } from '../recordsWithProps'\nimport { arrowShapeVersions } from '../shapes/TLArrowShape'\nimport { TLBaseBinding } from './TLBaseBinding'\n\n/**\n * Defines the snapping behavior for elbow-style arrows when binding to shapes.\n * Controls how the arrow segment aligns with the target shape's geometry.\n *\n * @example\n * ```ts\n * const binding: TLArrowBindingProps = {\n * terminal: 'end',\n * normalizedAnchor: { x: 0.5, y: 0.5 },\n * isExact: false,\n * isPrecise: true,\n * snap: 'edge' // Snap to shape edge\n * }\n * ```\n *\n * @public\n */\nexport const ElbowArrowSnap = T.literalEnum('center', 'edge-point', 'edge', 'none')\n/**\n * Type representing the possible elbow arrow snap modes.\n *\n * - `'center'` - Snap to the center of the target shape\n * - `'edge-point'` - Snap to a specific point on the shape's edge\n * - `'edge'` - Snap to the nearest edge of the shape\n * - `'none'` - No snapping behavior\n *\n * @public\n */\nexport type ElbowArrowSnap = T.TypeOf<typeof ElbowArrowSnap>\n\n/**\n * Properties that define how an arrow binds to a target shape.\n * These properties control the visual and behavioral aspects of the arrow-to-shape connection.\n *\n * @example\n * ```ts\n * const arrowBindingProps: TLArrowBindingProps = {\n * terminal: 'end', // Bind the arrow's end point\n * normalizedAnchor: { x: 0.5, y: 0.0 }, // Bind to top center of shape\n * isExact: true, // Arrow head enters the shape\n * isPrecise: true, // Use exact anchor position\n * snap: 'edge' // Snap to shape edge\n * }\n * ```\n *\n * @public\n */\nexport interface TLArrowBindingProps {\n\t/** Which end of the arrow is bound - either 'start' or 'end' */\n\tterminal: 'start' | 'end'\n\t/**\n\t * Normalized anchor point on the target shape (0,0 = top-left, 1,1 = bottom-right).\n\t * Coordinates are relative to the shape's bounding box.\n\t */\n\tnormalizedAnchor: VecModel\n\t/**\n\t * Whether the arrow head 'enters' the bound shape to point directly at the binding\n\t * anchor point. When true, the arrow head will be positioned inside the target shape.\n\t */\n\tisExact: boolean\n\t/**\n\t * Whether to bind to the exact normalizedAnchor position, or to the center of the shape.\n\t * When false, the arrow will connect to the shape's center regardless of anchor position.\n\t */\n\tisPrecise: boolean\n\t/** Snapping behavior for elbow-style arrows */\n\tsnap: ElbowArrowSnap\n}\n\n/**\n * Validation schema for arrow binding properties.\n * Defines the runtime validation rules for each property in TLArrowBindingProps.\n *\n * @example\n * ```ts\n * import { arrowBindingProps } from '@tldraw/tlschema'\n *\n * // Use in custom shape schema\n * const customSchema = createTLSchema({\n * bindings: {\n * arrow: {\n * props: arrowBindingProps,\n * migrations: arrowBindingMigrations\n * }\n * }\n * })\n * ```\n *\n * @public\n */\nexport const arrowBindingProps: RecordProps<TLArrowBinding> = {\n\tterminal: T.literalEnum('start', 'end'),\n\tnormalizedAnchor: vecModelValidator,\n\tisExact: T.boolean,\n\tisPrecise: T.boolean,\n\tsnap: ElbowArrowSnap,\n}\n\n/**\n * Represents a binding relationship between an arrow shape and another shape.\n * Arrow bindings allow arrows to connect to and follow other shapes, maintaining\n * the connection even when shapes are moved or transformed.\n *\n * @example\n * ```ts\n * const arrowBinding: TLArrowBinding = {\n * id: 'binding:abc123',\n * typeName: 'binding',\n * type: 'arrow',\n * fromId: 'shape:arrow1', // The arrow shape\n * toId: 'shape:rectangle1', // The target shape\n * props: {\n * terminal: 'end',\n * normalizedAnchor: { x: 0.5, y: 0.5 },\n * isExact: false,\n * isPrecise: true,\n * snap: 'edge'\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport type TLArrowBinding = TLBaseBinding<'arrow', TLArrowBindingProps>\n\n/**\n * Version identifiers for arrow binding property migrations.\n * Each version represents a schema change that requires data migration.\n *\n * @example\n * ```ts\n * // Check if migration is needed\n * if (bindingVersion < arrowBindingVersions.AddSnap) {\n * // Apply AddSnap migration\n * }\n * ```\n *\n * @public\n */\nexport const arrowBindingVersions = createBindingPropsMigrationIds('arrow', {\n\tAddSnap: 1,\n})\n\n/**\n * Migration sequence for arrow binding properties.\n * Handles schema evolution over time by defining how to migrate data between versions.\n *\n * The sequence includes:\n * - **AddSnap (v1)**: Adds the `snap` property with default value 'none'\n *\n * @example\n * ```ts\n * import { arrowBindingMigrations } from '@tldraw/tlschema'\n *\n * // Apply migrations when loading older data\n * const migratedBinding = arrowBindingMigrations.migrate(oldBinding)\n * ```\n *\n * @public\n */\nexport const arrowBindingMigrations = createBindingPropsMigrationSequence({\n\tsequence: [\n\t\t{ dependsOn: [arrowShapeVersions.ExtractBindings] },\n\t\t{\n\t\t\tid: arrowBindingVersions.AddSnap,\n\t\t\tup: (props) => {\n\t\t\t\tprops.snap = 'none'\n\t\t\t},\n\t\t\tdown: (props) => {\n\t\t\t\tdelete props.snap\n\t\t\t},\n\t\t},\n\t],\n})\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAkB;AAClB,4BAA4C;AAC5C,uBAGO;AAEP,0BAAmC;AAoB5B,MAAM,iBAAiB,kBAAE,YAAY,UAAU,cAAc,QAAQ,MAAM;AAyE3E,MAAM,oBAAiD;AAAA,EAC7D,UAAU,kBAAE,YAAY,SAAS,KAAK;AAAA,EACtC,kBAAkB;AAAA,EAClB,SAAS,kBAAE;AAAA,EACX,WAAW,kBAAE;AAAA,EACb,MAAM;AACP;AA4CO,MAAM,2BAAuB,iDAA+B,SAAS;AAAA,EAC3E,SAAS;AACV,CAAC;AAmBM,MAAM,6BAAyB,sDAAoC;AAAA,EACzE,UAAU;AAAA,IACT,EAAE,WAAW,CAAC,uCAAmB,eAAe,EAAE;AAAA,IAClD;AAAA,MACC,IAAI,qBAAqB;AAAA,MACzB,IAAI,CAAC,UAAU;AACd,cAAM,OAAO;AAAA,MACd;AAAA,MACA,MAAM,CAAC,UAAU;AAChB,eAAO,MAAM;AAAA,MACd;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/bindings/TLBaseBinding.ts"],
4
- "sourcesContent": ["import { BaseRecord } from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { TLBindingId } from '../records/TLBinding'\nimport { TLShapeId } from '../records/TLShape'\nimport { shapeIdValidator } from '../shapes/TLBaseShape'\n\n/** @public */\nexport interface TLBaseBinding<Type extends string, Props extends object>\n\textends BaseRecord<'binding', TLBindingId> {\n\ttype: Type\n\tfromId: TLShapeId\n\ttoId: TLShapeId\n\tprops: Props\n\tmeta: JsonObject\n}\n\n/** @public */\nexport const bindingIdValidator = idValidator<TLBindingId>('binding')\n\n/** @public */\nexport function createBindingValidator<\n\tType extends string,\n\tProps extends JsonObject,\n\tMeta extends JsonObject,\n>(\n\ttype: Type,\n\tprops?: { [K in keyof Props]: T.Validatable<Props[K]> },\n\tmeta?: { [K in keyof Meta]: T.Validatable<Meta[K]> }\n) {\n\treturn T.object<TLBaseBinding<Type, Props>>({\n\t\tid: bindingIdValidator,\n\t\ttypeName: T.literal('binding'),\n\t\ttype: T.literal(type),\n\t\tfromId: shapeIdValidator,\n\t\ttoId: shapeIdValidator,\n\t\tprops: props ? T.object(props) : (T.jsonValue as any),\n\t\tmeta: meta ? T.object(meta) : (T.jsonValue as any),\n\t})\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAAkB;AAClB,0BAA4B;AAG5B,yBAAiC;AAa1B,MAAM,yBAAqB,iCAAyB,SAAS;AAG7D,SAAS,uBAKf,MACA,OACA,MACC;AACD,SAAO,kBAAE,OAAmC;AAAA,IAC3C,IAAI;AAAA,IACJ,UAAU,kBAAE,QAAQ,SAAS;AAAA,IAC7B,MAAM,kBAAE,QAAQ,IAAI;AAAA,IACpB,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO,QAAQ,kBAAE,OAAO,KAAK,IAAK,kBAAE;AAAA,IACpC,MAAM,OAAO,kBAAE,OAAO,IAAI,IAAK,kBAAE;AAAA,EAClC,CAAC;AACF;",
4
+ "sourcesContent": ["import { BaseRecord } from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { TLBindingId } from '../records/TLBinding'\nimport { TLShapeId } from '../records/TLShape'\nimport { shapeIdValidator } from '../shapes/TLBaseShape'\n\n/**\n * Base interface for all binding types in tldraw. Bindings represent relationships\n * between shapes, such as arrows connecting to other shapes or organizational connections.\n *\n * All bindings extend this base interface with specific type and property definitions.\n * The binding system enables shapes to maintain relationships that persist through\n * transformations, movements, and other operations.\n *\n * @param Type - String literal type identifying the specific binding type (e.g., 'arrow')\n * @param Props - Object containing binding-specific properties and configuration\n *\n * @example\n * ```ts\n * // Define a custom binding type\n * interface MyCustomBinding extends TLBaseBinding<'custom', MyCustomProps> {}\n *\n * interface MyCustomProps {\n * strength: number\n * color: string\n * }\n *\n * // Create a binding instance\n * const binding: MyCustomBinding = {\n * id: 'binding:abc123',\n * typeName: 'binding',\n * type: 'custom',\n * fromId: 'shape:source1',\n * toId: 'shape:target1',\n * props: {\n * strength: 0.8,\n * color: 'red'\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport interface TLBaseBinding<Type extends string, Props extends object>\n\textends BaseRecord<'binding', TLBindingId> {\n\t/** The specific type of this binding (e.g., 'arrow', 'custom') */\n\ttype: Type\n\t/** ID of the source shape in this binding relationship */\n\tfromId: TLShapeId\n\t/** ID of the target shape in this binding relationship */\n\ttoId: TLShapeId\n\t/** Binding-specific properties that define behavior and appearance */\n\tprops: Props\n\t/** User-defined metadata for extending binding functionality */\n\tmeta: JsonObject\n}\n\n/**\n * Validator for binding IDs. Ensures that binding identifiers follow the correct\n * format and type constraints required by the tldraw schema system.\n *\n * Used internally by the schema validation system to verify binding IDs when\n * records are created or modified. All binding IDs must be prefixed with 'binding:'.\n *\n * @example\n * ```ts\n * import { bindingIdValidator } from '@tldraw/tlschema'\n *\n * // Validate a binding ID\n * const isValid = bindingIdValidator.isValid('binding:abc123') // true\n * const isInvalid = bindingIdValidator.isValid('shape:abc123') // false\n *\n * // Use in custom validation schema\n * const customBindingValidator = T.object({\n * id: bindingIdValidator,\n * // ... other properties\n * })\n * ```\n *\n * @public\n */\nexport const bindingIdValidator = idValidator<TLBindingId>('binding')\n\n/**\n * Creates a runtime validator for a specific binding type. This factory function\n * generates a complete validation schema for custom bindings that extends TLBaseBinding.\n *\n * The validator ensures all binding records conform to the expected structure with\n * proper type safety and runtime validation. It validates the base binding properties\n * (id, type, fromId, toId) along with custom props and meta fields.\n *\n * @param type - The string literal type identifier for this binding (e.g., 'arrow', 'custom')\n * @param props - Optional validation schema for binding-specific properties\n * @param meta - Optional validation schema for metadata fields\n *\n * @returns A validator object that can validate complete binding records\n *\n * @example\n * ```ts\n * import { createBindingValidator } from '@tldraw/tlschema'\n * import { T } from '@tldraw/validate'\n *\n * // Create validator for a custom binding type\n * const myBindingValidator = createBindingValidator(\n * 'myBinding',\n * {\n * strength: T.number,\n * color: T.string,\n * enabled: T.boolean\n * },\n * {\n * createdAt: T.number,\n * author: T.string\n * }\n * )\n *\n * // Validate a binding instance\n * const bindingData = {\n * id: 'binding:123',\n * typeName: 'binding',\n * type: 'myBinding',\n * fromId: 'shape:abc',\n * toId: 'shape:def',\n * props: {\n * strength: 0.8,\n * color: 'red',\n * enabled: true\n * },\n * meta: {\n * createdAt: Date.now(),\n * author: 'user123'\n * }\n * }\n *\n * const isValid = myBindingValidator.isValid(bindingData) // true\n * ```\n *\n * @example\n * ```ts\n * // Simple binding without custom props or meta\n * const simpleBindingValidator = createBindingValidator('simple')\n *\n * // This will use JsonValue validation for props and meta\n * const binding = {\n * id: 'binding:456',\n * typeName: 'binding',\n * type: 'simple',\n * fromId: 'shape:start',\n * toId: 'shape:end',\n * props: {}, // Any JSON value allowed\n * meta: {} // Any JSON value allowed\n * }\n * ```\n *\n * @public\n */\nexport function createBindingValidator<\n\tType extends string,\n\tProps extends JsonObject,\n\tMeta extends JsonObject,\n>(\n\ttype: Type,\n\tprops?: { [K in keyof Props]: T.Validatable<Props[K]> },\n\tmeta?: { [K in keyof Meta]: T.Validatable<Meta[K]> }\n) {\n\treturn T.object<TLBaseBinding<Type, Props>>({\n\t\tid: bindingIdValidator,\n\t\ttypeName: T.literal('binding'),\n\t\ttype: T.literal(type),\n\t\tfromId: shapeIdValidator,\n\t\ttoId: shapeIdValidator,\n\t\tprops: props ? T.object(props) : (T.jsonValue as any),\n\t\tmeta: meta ? T.object(meta) : (T.jsonValue as any),\n\t})\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,sBAAkB;AAClB,0BAA4B;AAG5B,yBAAiC;AA8E1B,MAAM,yBAAqB,iCAAyB,SAAS;AA2E7D,SAAS,uBAKf,MACA,OACA,MACC;AACD,SAAO,kBAAE,OAAmC;AAAA,IAC3C,IAAI;AAAA,IACJ,UAAU,kBAAE,QAAQ,SAAS;AAAA,IAC7B,MAAM,kBAAE,QAAQ,IAAI;AAAA,IACpB,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO,QAAQ,kBAAE,OAAO,KAAK,IAAK,kBAAE;AAAA,IACpC,MAAM,OAAO,kBAAE,OAAO,IAAI,IAAK,kBAAE;AAAA,EAClC,CAAC;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/createPresenceStateDerivation.ts"],
4
- "sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { TLStore } from './TLStore'\nimport { CameraRecordType } from './records/TLCamera'\nimport { TLINSTANCE_ID } from './records/TLInstance'\nimport { InstancePageStateRecordType } from './records/TLPageState'\nimport { TLPOINTER_ID } from './records/TLPointer'\nimport { InstancePresenceRecordType, TLInstancePresence } from './records/TLPresence'\n\n/**\n * The information about a user which is used for multiplayer features.\n * @public\n */\nexport interface TLPresenceUserInfo {\n\t/**\n\t * id - A unique identifier for the user. This should be the same across all devices and sessions.\n\t */\n\tid: string\n\t/**\n\t * The user's display name.\n\t */\n\tname?: string | null\n\t/**\n\t * The user's color. If not given, a random color will be assigned.\n\t */\n\tcolor?: string | null\n}\n\n/**\n * Creates a derivation that represents the current presence state of the current user.\n * @public\n */\nexport function createPresenceStateDerivation(\n\t$user: Signal<TLPresenceUserInfo>,\n\tinstanceId?: TLInstancePresence['id']\n) {\n\treturn (store: TLStore): Signal<TLInstancePresence | null> => {\n\t\treturn computed('instancePresence', () => {\n\t\t\tconst user = $user.get()\n\t\t\tif (!user) return null\n\n\t\t\tconst state = getDefaultUserPresence(store, user)\n\t\t\tif (!state) return null\n\n\t\t\treturn InstancePresenceRecordType.create({\n\t\t\t\t...state,\n\t\t\t\tid: instanceId ?? InstancePresenceRecordType.createId(store.id),\n\t\t\t})\n\t\t})\n\t}\n}\n\n/** @public */\nexport type TLPresenceStateInfo = Parameters<(typeof InstancePresenceRecordType)['create']>[0]\n\n/** @public */\nexport function getDefaultUserPresence(store: TLStore, user: TLPresenceUserInfo) {\n\tconst instance = store.get(TLINSTANCE_ID)\n\tconst pageState = store.get(InstancePageStateRecordType.createId(instance?.currentPageId))\n\tconst camera = store.get(CameraRecordType.createId(instance?.currentPageId))\n\tconst pointer = store.get(TLPOINTER_ID)\n\tif (!pageState || !instance || !camera || !pointer) {\n\t\treturn null\n\t}\n\n\treturn {\n\t\tselectedShapeIds: pageState.selectedShapeIds,\n\t\tbrush: instance.brush,\n\t\tscribbles: instance.scribbles,\n\t\tuserId: user.id,\n\t\tuserName: user.name ?? '',\n\t\tfollowingUserId: instance.followingUserId,\n\t\tcamera: {\n\t\t\tx: camera.x,\n\t\t\ty: camera.y,\n\t\t\tz: camera.z,\n\t\t},\n\t\tcolor: user.color ?? '#FF0000',\n\t\tcurrentPageId: instance.currentPageId,\n\t\tcursor: {\n\t\t\tx: pointer.x,\n\t\t\ty: pointer.y,\n\t\t\trotation: instance.cursor.rotation,\n\t\t\ttype: instance.cursor.type,\n\t\t},\n\t\tlastActivityTimestamp: pointer.lastActivityTimestamp,\n\t\tscreenBounds: instance.screenBounds,\n\t\tchatMessage: instance.chatMessage,\n\t\tmeta: {},\n\t} satisfies TLPresenceStateInfo\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiC;AAEjC,sBAAiC;AACjC,wBAA8B;AAC9B,yBAA4C;AAC5C,uBAA6B;AAC7B,wBAA+D;AAyBxD,SAAS,8BACf,OACA,YACC;AACD,SAAO,CAAC,UAAsD;AAC7D,eAAO,uBAAS,oBAAoB,MAAM;AACzC,YAAM,OAAO,MAAM,IAAI;AACvB,UAAI,CAAC,KAAM,QAAO;AAElB,YAAM,QAAQ,uBAAuB,OAAO,IAAI;AAChD,UAAI,CAAC,MAAO,QAAO;AAEnB,aAAO,6CAA2B,OAAO;AAAA,QACxC,GAAG;AAAA,QACH,IAAI,cAAc,6CAA2B,SAAS,MAAM,EAAE;AAAA,MAC/D,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AACD;AAMO,SAAS,uBAAuB,OAAgB,MAA0B;AAChF,QAAM,WAAW,MAAM,IAAI,+BAAa;AACxC,QAAM,YAAY,MAAM,IAAI,+CAA4B,SAAS,UAAU,aAAa,CAAC;AACzF,QAAM,SAAS,MAAM,IAAI,iCAAiB,SAAS,UAAU,aAAa,CAAC;AAC3E,QAAM,UAAU,MAAM,IAAI,6BAAY;AACtC,MAAI,CAAC,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS;AACnD,WAAO;AAAA,EACR;AAEA,SAAO;AAAA,IACN,kBAAkB,UAAU;AAAA,IAC5B,OAAO,SAAS;AAAA,IAChB,WAAW,SAAS;AAAA,IACpB,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK,QAAQ;AAAA,IACvB,iBAAiB,SAAS;AAAA,IAC1B,QAAQ;AAAA,MACP,GAAG,OAAO;AAAA,MACV,GAAG,OAAO;AAAA,MACV,GAAG,OAAO;AAAA,IACX;AAAA,IACA,OAAO,KAAK,SAAS;AAAA,IACrB,eAAe,SAAS;AAAA,IACxB,QAAQ;AAAA,MACP,GAAG,QAAQ;AAAA,MACX,GAAG,QAAQ;AAAA,MACX,UAAU,SAAS,OAAO;AAAA,MAC1B,MAAM,SAAS,OAAO;AAAA,IACvB;AAAA,IACA,uBAAuB,QAAQ;AAAA,IAC/B,cAAc,SAAS;AAAA,IACvB,aAAa,SAAS;AAAA,IACtB,MAAM,CAAC;AAAA,EACR;AACD;",
4
+ "sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { TLStore } from './TLStore'\nimport { CameraRecordType } from './records/TLCamera'\nimport { TLINSTANCE_ID } from './records/TLInstance'\nimport { InstancePageStateRecordType } from './records/TLPageState'\nimport { TLPOINTER_ID } from './records/TLPointer'\nimport { InstancePresenceRecordType, TLInstancePresence } from './records/TLPresence'\n\n/**\n * The information about a user which is used for multiplayer features.\n * @public\n */\nexport interface TLPresenceUserInfo {\n\t/**\n\t * id - A unique identifier for the user. This should be the same across all devices and sessions.\n\t */\n\tid: string\n\t/**\n\t * The user's display name.\n\t */\n\tname?: string | null\n\t/**\n\t * The user's color. If not given, a random color will be assigned.\n\t */\n\tcolor?: string | null\n}\n\n/**\n * Creates a derivation that represents the current presence state of the current user.\n *\n * This function returns a derivation factory that, when given a store, creates a computed signal\n * containing the user's current presence state. The presence state includes information like cursor\n * position, selected shapes, camera position, and user metadata that gets synchronized in\n * multiplayer scenarios.\n *\n * @param $user - A reactive signal containing the user information\n * @param instanceId - Optional custom instance ID. If not provided, one will be generated based on the store ID\n * @returns A function that takes a store and returns a computed signal of the user's presence state\n *\n * @example\n * ```ts\n * import { createPresenceStateDerivation } from '@tldraw/tlschema'\n * import { atom } from '@tldraw/state'\n *\n * const userSignal = atom('user', { id: 'user-123', name: 'Alice', color: '#ff0000' })\n * const presenceDerivation = createPresenceStateDerivation(userSignal)\n *\n * // Use with a store to get reactive presence state\n * const presenceState = presenceDerivation(store)\n * console.log(presenceState.get()) // Current user presence or null\n * ```\n *\n * @public\n */\nexport function createPresenceStateDerivation(\n\t$user: Signal<TLPresenceUserInfo>,\n\tinstanceId?: TLInstancePresence['id']\n) {\n\treturn (store: TLStore): Signal<TLInstancePresence | null> => {\n\t\treturn computed('instancePresence', () => {\n\t\t\tconst user = $user.get()\n\t\t\tif (!user) return null\n\n\t\t\tconst state = getDefaultUserPresence(store, user)\n\t\t\tif (!state) return null\n\n\t\t\treturn InstancePresenceRecordType.create({\n\t\t\t\t...state,\n\t\t\t\tid: instanceId ?? InstancePresenceRecordType.createId(store.id),\n\t\t\t})\n\t\t})\n\t}\n}\n\n/**\n * The shape of data used to create a presence record.\n *\n * This type represents all the properties needed to construct a TLInstancePresence record.\n * It includes user information, cursor state, camera position, selected shapes, and other\n * presence-related data that gets synchronized across multiplayer clients.\n *\n * @public\n */\nexport type TLPresenceStateInfo = Parameters<(typeof InstancePresenceRecordType)['create']>[0]\n\n/**\n * Creates default presence state information for a user based on the current store state.\n *\n * This function extracts the current state from various store records (instance, page state,\n * camera, pointer) and combines them with user information to create a complete presence\n * state object. This is commonly used as a starting point for custom presence implementations.\n *\n * @param store - The tldraw store containing the current editor state\n * @param user - The user information to include in the presence state\n * @returns The default presence state info, or null if required store records are missing\n *\n * @example\n * ```ts\n * import { getDefaultUserPresence } from '@tldraw/tlschema'\n *\n * const user = { id: 'user-123', name: 'Alice', color: '#ff0000' }\n * const presenceInfo = getDefaultUserPresence(store, user)\n *\n * if (presenceInfo) {\n * console.log('Current cursor:', presenceInfo.cursor)\n * console.log('Selected shapes:', presenceInfo.selectedShapeIds)\n * console.log('Camera position:', presenceInfo.camera)\n * }\n * ```\n *\n * @example\n * ```ts\n * // Common pattern: customize default presence\n * const customPresence = {\n * ...getDefaultUserPresence(store, user),\n * // Remove camera for privacy\n * camera: undefined,\n * // Add custom metadata\n * customField: 'my-data'\n * }\n * ```\n *\n * @public\n */\nexport function getDefaultUserPresence(store: TLStore, user: TLPresenceUserInfo) {\n\tconst instance = store.get(TLINSTANCE_ID)\n\tconst pageState = store.get(InstancePageStateRecordType.createId(instance?.currentPageId))\n\tconst camera = store.get(CameraRecordType.createId(instance?.currentPageId))\n\tconst pointer = store.get(TLPOINTER_ID)\n\tif (!pageState || !instance || !camera || !pointer) {\n\t\treturn null\n\t}\n\n\treturn {\n\t\tselectedShapeIds: pageState.selectedShapeIds,\n\t\tbrush: instance.brush,\n\t\tscribbles: instance.scribbles,\n\t\tuserId: user.id,\n\t\tuserName: user.name ?? '',\n\t\tfollowingUserId: instance.followingUserId,\n\t\tcamera: {\n\t\t\tx: camera.x,\n\t\t\ty: camera.y,\n\t\t\tz: camera.z,\n\t\t},\n\t\tcolor: user.color ?? '#FF0000',\n\t\tcurrentPageId: instance.currentPageId,\n\t\tcursor: {\n\t\t\tx: pointer.x,\n\t\t\ty: pointer.y,\n\t\t\trotation: instance.cursor.rotation,\n\t\t\ttype: instance.cursor.type,\n\t\t},\n\t\tlastActivityTimestamp: pointer.lastActivityTimestamp,\n\t\tscreenBounds: instance.screenBounds,\n\t\tchatMessage: instance.chatMessage,\n\t\tmeta: {},\n\t} satisfies TLPresenceStateInfo\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiC;AAEjC,sBAAiC;AACjC,wBAA8B;AAC9B,yBAA4C;AAC5C,uBAA6B;AAC7B,wBAA+D;AAgDxD,SAAS,8BACf,OACA,YACC;AACD,SAAO,CAAC,UAAsD;AAC7D,eAAO,uBAAS,oBAAoB,MAAM;AACzC,YAAM,OAAO,MAAM,IAAI;AACvB,UAAI,CAAC,KAAM,QAAO;AAElB,YAAM,QAAQ,uBAAuB,OAAO,IAAI;AAChD,UAAI,CAAC,MAAO,QAAO;AAEnB,aAAO,6CAA2B,OAAO;AAAA,QACxC,GAAG;AAAA,QACH,IAAI,cAAc,6CAA2B,SAAS,MAAM,EAAE;AAAA,MAC/D,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AACD;AAoDO,SAAS,uBAAuB,OAAgB,MAA0B;AAChF,QAAM,WAAW,MAAM,IAAI,+BAAa;AACxC,QAAM,YAAY,MAAM,IAAI,+CAA4B,SAAS,UAAU,aAAa,CAAC;AACzF,QAAM,SAAS,MAAM,IAAI,iCAAiB,SAAS,UAAU,aAAa,CAAC;AAC3E,QAAM,UAAU,MAAM,IAAI,6BAAY;AACtC,MAAI,CAAC,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS;AACnD,WAAO;AAAA,EACR;AAEA,SAAO;AAAA,IACN,kBAAkB,UAAU;AAAA,IAC5B,OAAO,SAAS;AAAA,IAChB,WAAW,SAAS;AAAA,IACpB,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK,QAAQ;AAAA,IACvB,iBAAiB,SAAS;AAAA,IAC1B,QAAQ;AAAA,MACP,GAAG,OAAO;AAAA,MACV,GAAG,OAAO;AAAA,MACV,GAAG,OAAO;AAAA,IACX;AAAA,IACA,OAAO,KAAK,SAAS;AAAA,IACrB,eAAe,SAAS;AAAA,IACxB,QAAQ;AAAA,MACP,GAAG,QAAQ;AAAA,MACX,GAAG,QAAQ;AAAA,MACX,UAAU,SAAS,OAAO;AAAA,MAC1B,MAAM,SAAS,OAAO;AAAA,IACvB;AAAA,IACA,uBAAuB,QAAQ;AAAA,IAC/B,cAAc,SAAS;AAAA,IACvB,aAAa,SAAS;AAAA,IACtB,MAAM,CAAC;AAAA,EACR;AACD;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/createTLSchema.ts"],
4
- "sourcesContent": ["import { LegacyMigrations, MigrationSequence, StoreSchema, StoreValidator } from '@tldraw/store'\nimport { objectMapValues } from '@tldraw/utils'\nimport { TLStoreProps, createIntegrityChecker, onValidationFailure } from './TLStore'\nimport { bookmarkAssetMigrations } from './assets/TLBookmarkAsset'\nimport { imageAssetMigrations } from './assets/TLImageAsset'\nimport { videoAssetMigrations } from './assets/TLVideoAsset'\nimport { arrowBindingMigrations, arrowBindingProps } from './bindings/TLArrowBinding'\nimport { AssetRecordType, assetMigrations } from './records/TLAsset'\nimport { TLBinding, TLDefaultBinding, createBindingRecordType } from './records/TLBinding'\nimport { CameraRecordType, cameraMigrations } from './records/TLCamera'\nimport { DocumentRecordType, documentMigrations } from './records/TLDocument'\nimport { createInstanceRecordType, instanceMigrations } from './records/TLInstance'\nimport { PageRecordType, pageMigrations } from './records/TLPage'\nimport { InstancePageStateRecordType, instancePageStateMigrations } from './records/TLPageState'\nimport { PointerRecordType, pointerMigrations } from './records/TLPointer'\nimport { InstancePresenceRecordType, instancePresenceMigrations } from './records/TLPresence'\nimport { TLRecord } from './records/TLRecord'\nimport {\n\tTLDefaultShape,\n\tTLShape,\n\tcreateShapeRecordType,\n\tgetShapePropKeysByStyle,\n\trootShapeMigrations,\n} from './records/TLShape'\nimport { TLPropsMigrations, processPropsMigrations } from './recordsWithProps'\nimport { arrowShapeMigrations, arrowShapeProps } from './shapes/TLArrowShape'\nimport { bookmarkShapeMigrations, bookmarkShapeProps } from './shapes/TLBookmarkShape'\nimport { drawShapeMigrations, drawShapeProps } from './shapes/TLDrawShape'\nimport { embedShapeMigrations, embedShapeProps } from './shapes/TLEmbedShape'\nimport { frameShapeMigrations, frameShapeProps } from './shapes/TLFrameShape'\nimport { geoShapeMigrations, geoShapeProps } from './shapes/TLGeoShape'\nimport { groupShapeMigrations, groupShapeProps } from './shapes/TLGroupShape'\nimport { highlightShapeMigrations, highlightShapeProps } from './shapes/TLHighlightShape'\nimport { imageShapeMigrations, imageShapeProps } from './shapes/TLImageShape'\nimport { lineShapeMigrations, lineShapeProps } from './shapes/TLLineShape'\nimport { noteShapeMigrations, noteShapeProps } from './shapes/TLNoteShape'\nimport { textShapeMigrations, textShapeProps } from './shapes/TLTextShape'\nimport { videoShapeMigrations, videoShapeProps } from './shapes/TLVideoShape'\nimport { storeMigrations } from './store-migrations'\nimport { StyleProp } from './styles/StyleProp'\n\n/** @public */\nexport interface SchemaPropsInfo {\n\tmigrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n\tprops?: Record<string, StoreValidator<any>>\n\tmeta?: Record<string, StoreValidator<any>>\n}\n\n/** @public */\nexport type TLSchema = StoreSchema<TLRecord, TLStoreProps>\n\n/** @public */\nexport const defaultShapeSchemas = {\n\tarrow: { migrations: arrowShapeMigrations, props: arrowShapeProps },\n\tbookmark: { migrations: bookmarkShapeMigrations, props: bookmarkShapeProps },\n\tdraw: { migrations: drawShapeMigrations, props: drawShapeProps },\n\tembed: { migrations: embedShapeMigrations, props: embedShapeProps },\n\tframe: { migrations: frameShapeMigrations, props: frameShapeProps },\n\tgeo: { migrations: geoShapeMigrations, props: geoShapeProps },\n\tgroup: { migrations: groupShapeMigrations, props: groupShapeProps },\n\thighlight: { migrations: highlightShapeMigrations, props: highlightShapeProps },\n\timage: { migrations: imageShapeMigrations, props: imageShapeProps },\n\tline: { migrations: lineShapeMigrations, props: lineShapeProps },\n\tnote: { migrations: noteShapeMigrations, props: noteShapeProps },\n\ttext: { migrations: textShapeMigrations, props: textShapeProps },\n\tvideo: { migrations: videoShapeMigrations, props: videoShapeProps },\n} satisfies { [T in TLDefaultShape['type']]: SchemaPropsInfo }\n\n/** @public */\nexport const defaultBindingSchemas = {\n\tarrow: { migrations: arrowBindingMigrations, props: arrowBindingProps },\n} satisfies { [T in TLDefaultBinding['type']]: SchemaPropsInfo }\n\n/**\n * Create a TLSchema with custom shapes. Custom shapes cannot override default shapes.\n *\n * @param opts - Options\n *\n * @public */\nexport function createTLSchema({\n\tshapes = defaultShapeSchemas,\n\tbindings = defaultBindingSchemas,\n\tmigrations,\n}: {\n\tshapes?: Record<string, SchemaPropsInfo>\n\tbindings?: Record<string, SchemaPropsInfo>\n\tmigrations?: readonly MigrationSequence[]\n} = {}): TLSchema {\n\tconst stylesById = new Map<string, StyleProp<unknown>>()\n\tfor (const shape of objectMapValues(shapes)) {\n\t\tfor (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) {\n\t\t\tif (stylesById.has(style.id) && stylesById.get(style.id) !== style) {\n\t\t\t\tthrow new Error(`Multiple StyleProp instances with the same id: ${style.id}`)\n\t\t\t}\n\t\t\tstylesById.set(style.id, style)\n\t\t}\n\t}\n\n\tconst ShapeRecordType = createShapeRecordType(shapes)\n\tconst BindingRecordType = createBindingRecordType(bindings)\n\tconst InstanceRecordType = createInstanceRecordType(stylesById)\n\n\treturn StoreSchema.create(\n\t\t{\n\t\t\tasset: AssetRecordType,\n\t\t\tbinding: BindingRecordType,\n\t\t\tcamera: CameraRecordType,\n\t\t\tdocument: DocumentRecordType,\n\t\t\tinstance: InstanceRecordType,\n\t\t\tinstance_page_state: InstancePageStateRecordType,\n\t\t\tpage: PageRecordType,\n\t\t\tinstance_presence: InstancePresenceRecordType,\n\t\t\tpointer: PointerRecordType,\n\t\t\tshape: ShapeRecordType,\n\t\t},\n\t\t{\n\t\t\tmigrations: [\n\t\t\t\tstoreMigrations,\n\t\t\t\tassetMigrations,\n\t\t\t\tcameraMigrations,\n\t\t\t\tdocumentMigrations,\n\t\t\t\tinstanceMigrations,\n\t\t\t\tinstancePageStateMigrations,\n\t\t\t\tpageMigrations,\n\t\t\t\tinstancePresenceMigrations,\n\t\t\t\tpointerMigrations,\n\t\t\t\trootShapeMigrations,\n\n\t\t\t\tbookmarkAssetMigrations,\n\t\t\t\timageAssetMigrations,\n\t\t\t\tvideoAssetMigrations,\n\n\t\t\t\t...processPropsMigrations<TLShape>('shape', shapes),\n\t\t\t\t...processPropsMigrations<TLBinding>('binding', bindings),\n\n\t\t\t\t...(migrations ?? []),\n\t\t\t],\n\t\t\tonValidationFailure,\n\t\t\tcreateIntegrityChecker,\n\t\t}\n\t)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiF;AACjF,mBAAgC;AAChC,qBAA0E;AAC1E,6BAAwC;AACxC,0BAAqC;AACrC,0BAAqC;AACrC,4BAA0D;AAC1D,qBAAiD;AACjD,uBAAqE;AACrE,sBAAmD;AACnD,wBAAuD;AACvD,wBAA6D;AAC7D,oBAA+C;AAC/C,yBAAyE;AACzE,uBAAqD;AACrD,wBAAuE;AAEvE,qBAMO;AACP,8BAA0D;AAC1D,0BAAsD;AACtD,6BAA4D;AAC5D,yBAAoD;AACpD,0BAAsD;AACtD,0BAAsD;AACtD,wBAAkD;AAClD,0BAAsD;AACtD,8BAA8D;AAC9D,0BAAsD;AACtD,yBAAoD;AACpD,yBAAoD;AACpD,yBAAoD;AACpD,0BAAsD;AACtD,8BAAgC;AAczB,MAAM,sBAAsB;AAAA,EAClC,OAAO,EAAE,YAAY,0CAAsB,OAAO,oCAAgB;AAAA,EAClE,UAAU,EAAE,YAAY,gDAAyB,OAAO,0CAAmB;AAAA,EAC3E,MAAM,EAAE,YAAY,wCAAqB,OAAO,kCAAe;AAAA,EAC/D,OAAO,EAAE,YAAY,0CAAsB,OAAO,oCAAgB;AAAA,EAClE,OAAO,EAAE,YAAY,0CAAsB,OAAO,oCAAgB;AAAA,EAClE,KAAK,EAAE,YAAY,sCAAoB,OAAO,gCAAc;AAAA,EAC5D,OAAO,EAAE,YAAY,0CAAsB,OAAO,oCAAgB;AAAA,EAClE,WAAW,EAAE,YAAY,kDAA0B,OAAO,4CAAoB;AAAA,EAC9E,OAAO,EAAE,YAAY,0CAAsB,OAAO,oCAAgB;AAAA,EAClE,MAAM,EAAE,YAAY,wCAAqB,OAAO,kCAAe;AAAA,EAC/D,MAAM,EAAE,YAAY,wCAAqB,OAAO,kCAAe;AAAA,EAC/D,MAAM,EAAE,YAAY,wCAAqB,OAAO,kCAAe;AAAA,EAC/D,OAAO,EAAE,YAAY,0CAAsB,OAAO,oCAAgB;AACnE;AAGO,MAAM,wBAAwB;AAAA,EACpC,OAAO,EAAE,YAAY,8CAAwB,OAAO,wCAAkB;AACvE;AAQO,SAAS,eAAe;AAAA,EAC9B,SAAS;AAAA,EACT,WAAW;AAAA,EACX;AACD,IAII,CAAC,GAAa;AACjB,QAAM,aAAa,oBAAI,IAAgC;AACvD,aAAW,aAAS,8BAAgB,MAAM,GAAG;AAC5C,eAAW,aAAS,wCAAwB,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG;AACtE,UAAI,WAAW,IAAI,MAAM,EAAE,KAAK,WAAW,IAAI,MAAM,EAAE,MAAM,OAAO;AACnE,cAAM,IAAI,MAAM,kDAAkD,MAAM,EAAE,EAAE;AAAA,MAC7E;AACA,iBAAW,IAAI,MAAM,IAAI,KAAK;AAAA,IAC/B;AAAA,EACD;AAEA,QAAM,sBAAkB,sCAAsB,MAAM;AACpD,QAAM,wBAAoB,0CAAwB,QAAQ;AAC1D,QAAM,yBAAqB,4CAAyB,UAAU;AAE9D,SAAO,yBAAY;AAAA,IAClB;AAAA,MACC,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,qBAAqB;AAAA,MACrB,MAAM;AAAA,MACN,mBAAmB;AAAA,MACnB,SAAS;AAAA,MACT,OAAO;AAAA,IACR;AAAA,IACA;AAAA,MACC,YAAY;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QAEA,OAAG,gDAAgC,SAAS,MAAM;AAAA,QAClD,OAAG,gDAAkC,WAAW,QAAQ;AAAA,QAExD,GAAI,cAAc,CAAC;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["import { LegacyMigrations, MigrationSequence, StoreSchema, StoreValidator } from '@tldraw/store'\nimport { objectMapValues } from '@tldraw/utils'\nimport { TLStoreProps, createIntegrityChecker, onValidationFailure } from './TLStore'\nimport { bookmarkAssetMigrations } from './assets/TLBookmarkAsset'\nimport { imageAssetMigrations } from './assets/TLImageAsset'\nimport { videoAssetMigrations } from './assets/TLVideoAsset'\nimport { arrowBindingMigrations, arrowBindingProps } from './bindings/TLArrowBinding'\nimport { AssetRecordType, assetMigrations } from './records/TLAsset'\nimport { TLBinding, TLDefaultBinding, createBindingRecordType } from './records/TLBinding'\nimport { CameraRecordType, cameraMigrations } from './records/TLCamera'\nimport { DocumentRecordType, documentMigrations } from './records/TLDocument'\nimport { createInstanceRecordType, instanceMigrations } from './records/TLInstance'\nimport { PageRecordType, pageMigrations } from './records/TLPage'\nimport { InstancePageStateRecordType, instancePageStateMigrations } from './records/TLPageState'\nimport { PointerRecordType, pointerMigrations } from './records/TLPointer'\nimport { InstancePresenceRecordType, instancePresenceMigrations } from './records/TLPresence'\nimport { TLRecord } from './records/TLRecord'\nimport {\n\tTLDefaultShape,\n\tTLShape,\n\tcreateShapeRecordType,\n\tgetShapePropKeysByStyle,\n\trootShapeMigrations,\n} from './records/TLShape'\nimport { TLPropsMigrations, processPropsMigrations } from './recordsWithProps'\nimport { arrowShapeMigrations, arrowShapeProps } from './shapes/TLArrowShape'\nimport { bookmarkShapeMigrations, bookmarkShapeProps } from './shapes/TLBookmarkShape'\nimport { drawShapeMigrations, drawShapeProps } from './shapes/TLDrawShape'\nimport { embedShapeMigrations, embedShapeProps } from './shapes/TLEmbedShape'\nimport { frameShapeMigrations, frameShapeProps } from './shapes/TLFrameShape'\nimport { geoShapeMigrations, geoShapeProps } from './shapes/TLGeoShape'\nimport { groupShapeMigrations, groupShapeProps } from './shapes/TLGroupShape'\nimport { highlightShapeMigrations, highlightShapeProps } from './shapes/TLHighlightShape'\nimport { imageShapeMigrations, imageShapeProps } from './shapes/TLImageShape'\nimport { lineShapeMigrations, lineShapeProps } from './shapes/TLLineShape'\nimport { noteShapeMigrations, noteShapeProps } from './shapes/TLNoteShape'\nimport { textShapeMigrations, textShapeProps } from './shapes/TLTextShape'\nimport { videoShapeMigrations, videoShapeProps } from './shapes/TLVideoShape'\nimport { storeMigrations } from './store-migrations'\nimport { StyleProp } from './styles/StyleProp'\n\n/**\n * Configuration information for a schema type (shape or binding), including its properties,\n * metadata, and migration sequences for data evolution over time.\n *\n * @public\n * @example\n * ```ts\n * import { arrowShapeMigrations, arrowShapeProps } from './shapes/TLArrowShape'\n *\n * const myShapeSchema: SchemaPropsInfo = {\n * migrations: arrowShapeMigrations,\n * props: arrowShapeProps,\n * meta: {\n * customField: T.string,\n * },\n * }\n * ```\n */\nexport interface SchemaPropsInfo {\n\t/**\n\t * Migration sequences for handling data evolution over time. Can be legacy migrations,\n\t * props-specific migrations, or general migration sequences.\n\t */\n\tmigrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n\n\t/**\n\t * Validation schema for the shape or binding properties. Maps property names to their validators.\n\t */\n\tprops?: Record<string, StoreValidator<any>>\n\n\t/**\n\t * Validation schema for metadata fields. Maps metadata field names to their validators.\n\t */\n\tmeta?: Record<string, StoreValidator<any>>\n}\n\n/**\n * The complete schema definition for a tldraw store, encompassing all record types,\n * validation rules, and migration sequences. This schema defines the structure of\n * the persistent data model used by tldraw.\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas } from '@tldraw/tlschema'\n * import { Store } from '@tldraw/store'\n *\n * const schema: TLSchema = createTLSchema({\n * shapes: defaultShapeSchemas,\n * })\n *\n * const store = new Store({ schema })\n * ```\n */\nexport type TLSchema = StoreSchema<TLRecord, TLStoreProps>\n\n/**\n * Default shape schema configurations for all built-in tldraw shape types.\n * Each shape type includes its validation props and migration sequences.\n *\n * This object contains schema information for:\n * - arrow: Directional lines that can bind to other shapes\n * - bookmark: Website bookmark cards with preview information\n * - draw: Freehand drawing paths created with drawing tools\n * - embed: Embedded content from external services (YouTube, Figma, etc.)\n * - frame: Container shapes for organizing content\n * - geo: Geometric shapes (rectangles, ellipses, triangles, etc.)\n * - group: Logical groupings of multiple shapes\n * - highlight: Highlighting strokes from the highlighter tool\n * - image: Raster image shapes referencing image assets\n * - line: Multi-point lines and splines\n * - note: Sticky note shapes with text content\n * - text: Rich text shapes with formatting support\n * - video: Video shapes referencing video assets\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas } from '@tldraw/tlschema'\n *\n * // Use all default shapes\n * const schema = createTLSchema({\n * shapes: defaultShapeSchemas,\n * })\n *\n * // Use only specific default shapes\n * const minimalSchema = createTLSchema({\n * shapes: {\n * geo: defaultShapeSchemas.geo,\n * text: defaultShapeSchemas.text,\n * },\n * })\n * ```\n */\nexport const defaultShapeSchemas = {\n\tarrow: { migrations: arrowShapeMigrations, props: arrowShapeProps },\n\tbookmark: { migrations: bookmarkShapeMigrations, props: bookmarkShapeProps },\n\tdraw: { migrations: drawShapeMigrations, props: drawShapeProps },\n\tembed: { migrations: embedShapeMigrations, props: embedShapeProps },\n\tframe: { migrations: frameShapeMigrations, props: frameShapeProps },\n\tgeo: { migrations: geoShapeMigrations, props: geoShapeProps },\n\tgroup: { migrations: groupShapeMigrations, props: groupShapeProps },\n\thighlight: { migrations: highlightShapeMigrations, props: highlightShapeProps },\n\timage: { migrations: imageShapeMigrations, props: imageShapeProps },\n\tline: { migrations: lineShapeMigrations, props: lineShapeProps },\n\tnote: { migrations: noteShapeMigrations, props: noteShapeProps },\n\ttext: { migrations: textShapeMigrations, props: textShapeProps },\n\tvideo: { migrations: videoShapeMigrations, props: videoShapeProps },\n} satisfies { [T in TLDefaultShape['type']]: SchemaPropsInfo }\n\n/**\n * Default binding schema configurations for all built-in tldraw binding types.\n * Bindings represent relationships between shapes, such as arrows connected to shapes.\n *\n * Currently includes:\n * - arrow: Bindings that connect arrow shapes to other shapes at specific anchor points\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultBindingSchemas } from '@tldraw/tlschema'\n *\n * // Use default bindings\n * const schema = createTLSchema({\n * bindings: defaultBindingSchemas,\n * })\n *\n * // Add custom binding alongside defaults\n * const customSchema = createTLSchema({\n * bindings: {\n * ...defaultBindingSchemas,\n * myCustomBinding: {\n * props: myCustomBindingProps,\n * migrations: myCustomBindingMigrations,\n * },\n * },\n * })\n * ```\n */\nexport const defaultBindingSchemas = {\n\tarrow: { migrations: arrowBindingMigrations, props: arrowBindingProps },\n} satisfies { [T in TLDefaultBinding['type']]: SchemaPropsInfo }\n\n/**\n * Creates a complete TLSchema for use with tldraw stores. This schema defines the structure,\n * validation, and migration sequences for all record types in a tldraw application.\n *\n * The schema includes all core record types (pages, cameras, instances, etc.) plus the\n * shape and binding types you specify. Style properties are automatically collected from\n * all shapes to ensure consistency across the application.\n *\n * @param options - Configuration options for the schema\n * - shapes - Shape schema configurations. Defaults to defaultShapeSchemas if not provided\n * - bindings - Binding schema configurations. Defaults to defaultBindingSchemas if not provided\n * - migrations - Additional migration sequences to include in the schema\n * @returns A complete TLSchema ready for use with Store creation\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas, defaultBindingSchemas } from '@tldraw/tlschema'\n * import { Store } from '@tldraw/store'\n *\n * // Create schema with all default shapes and bindings\n * const schema = createTLSchema()\n *\n * // Create schema with custom shapes added\n * const customSchema = createTLSchema({\n * shapes: {\n * ...defaultShapeSchemas,\n * myCustomShape: {\n * props: myCustomShapeProps,\n * migrations: myCustomShapeMigrations,\n * },\n * },\n * })\n *\n * // Create schema with only specific shapes\n * const minimalSchema = createTLSchema({\n * shapes: {\n * geo: defaultShapeSchemas.geo,\n * text: defaultShapeSchemas.text,\n * },\n * bindings: defaultBindingSchemas,\n * })\n *\n * // Use the schema with a store\n * const store = new Store({\n * schema: customSchema,\n * props: {\n * defaultName: 'My Drawing',\n * },\n * })\n * ```\n */\nexport function createTLSchema({\n\tshapes = defaultShapeSchemas,\n\tbindings = defaultBindingSchemas,\n\tmigrations,\n}: {\n\tshapes?: Record<string, SchemaPropsInfo>\n\tbindings?: Record<string, SchemaPropsInfo>\n\tmigrations?: readonly MigrationSequence[]\n} = {}): TLSchema {\n\tconst stylesById = new Map<string, StyleProp<unknown>>()\n\tfor (const shape of objectMapValues(shapes)) {\n\t\tfor (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) {\n\t\t\tif (stylesById.has(style.id) && stylesById.get(style.id) !== style) {\n\t\t\t\tthrow new Error(`Multiple StyleProp instances with the same id: ${style.id}`)\n\t\t\t}\n\t\t\tstylesById.set(style.id, style)\n\t\t}\n\t}\n\n\tconst ShapeRecordType = createShapeRecordType(shapes)\n\tconst BindingRecordType = createBindingRecordType(bindings)\n\tconst InstanceRecordType = createInstanceRecordType(stylesById)\n\n\treturn StoreSchema.create(\n\t\t{\n\t\t\tasset: AssetRecordType,\n\t\t\tbinding: BindingRecordType,\n\t\t\tcamera: CameraRecordType,\n\t\t\tdocument: DocumentRecordType,\n\t\t\tinstance: InstanceRecordType,\n\t\t\tinstance_page_state: InstancePageStateRecordType,\n\t\t\tpage: PageRecordType,\n\t\t\tinstance_presence: InstancePresenceRecordType,\n\t\t\tpointer: PointerRecordType,\n\t\t\tshape: ShapeRecordType,\n\t\t},\n\t\t{\n\t\t\tmigrations: [\n\t\t\t\tstoreMigrations,\n\t\t\t\tassetMigrations,\n\t\t\t\tcameraMigrations,\n\t\t\t\tdocumentMigrations,\n\t\t\t\tinstanceMigrations,\n\t\t\t\tinstancePageStateMigrations,\n\t\t\t\tpageMigrations,\n\t\t\t\tinstancePresenceMigrations,\n\t\t\t\tpointerMigrations,\n\t\t\t\trootShapeMigrations,\n\n\t\t\t\tbookmarkAssetMigrations,\n\t\t\t\timageAssetMigrations,\n\t\t\t\tvideoAssetMigrations,\n\n\t\t\t\t...processPropsMigrations<TLShape>('shape', shapes),\n\t\t\t\t...processPropsMigrations<TLBinding>('binding', bindings),\n\n\t\t\t\t...(migrations ?? []),\n\t\t\t],\n\t\t\tonValidationFailure,\n\t\t\tcreateIntegrityChecker,\n\t\t}\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }