@tldraw/tlschema 4.2.1 → 4.2.2

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 (117) hide show
  1. package/dist-cjs/bindings/TLBaseBinding.js.map +2 -2
  2. package/dist-cjs/createTLSchema.js.map +2 -2
  3. package/dist-cjs/index.d.ts +242 -71
  4. package/dist-cjs/index.js +4 -1
  5. package/dist-cjs/index.js.map +2 -2
  6. package/dist-cjs/misc/TLOpacity.js +1 -5
  7. package/dist-cjs/misc/TLOpacity.js.map +2 -2
  8. package/dist-cjs/misc/TLRichText.js +5 -1
  9. package/dist-cjs/misc/TLRichText.js.map +2 -2
  10. package/dist-cjs/misc/b64Vecs.js +224 -0
  11. package/dist-cjs/misc/b64Vecs.js.map +7 -0
  12. package/dist-cjs/records/TLAsset.js.map +1 -1
  13. package/dist-cjs/records/TLBinding.js.map +2 -2
  14. package/dist-cjs/records/TLShape.js.map +2 -2
  15. package/dist-cjs/shapes/ShapeWithCrop.js.map +1 -1
  16. package/dist-cjs/shapes/TLArrowShape.js +26 -13
  17. package/dist-cjs/shapes/TLArrowShape.js.map +2 -2
  18. package/dist-cjs/shapes/TLBaseShape.js.map +2 -2
  19. package/dist-cjs/shapes/TLDrawShape.js +37 -4
  20. package/dist-cjs/shapes/TLDrawShape.js.map +2 -2
  21. package/dist-cjs/shapes/TLEmbedShape.js +17 -0
  22. package/dist-cjs/shapes/TLEmbedShape.js.map +2 -2
  23. package/dist-cjs/shapes/TLGeoShape.js +12 -1
  24. package/dist-cjs/shapes/TLGeoShape.js.map +2 -2
  25. package/dist-cjs/shapes/TLHighlightShape.js +29 -2
  26. package/dist-cjs/shapes/TLHighlightShape.js.map +2 -2
  27. package/dist-cjs/shapes/TLNoteShape.js +12 -1
  28. package/dist-cjs/shapes/TLNoteShape.js.map +2 -2
  29. package/dist-cjs/shapes/TLTextShape.js +12 -1
  30. package/dist-cjs/shapes/TLTextShape.js.map +2 -2
  31. package/dist-cjs/store-migrations.js +15 -15
  32. package/dist-cjs/store-migrations.js.map +2 -2
  33. package/dist-esm/bindings/TLBaseBinding.mjs.map +2 -2
  34. package/dist-esm/createTLSchema.mjs.map +2 -2
  35. package/dist-esm/index.d.mts +242 -71
  36. package/dist-esm/index.mjs +5 -1
  37. package/dist-esm/index.mjs.map +2 -2
  38. package/dist-esm/misc/TLOpacity.mjs +1 -5
  39. package/dist-esm/misc/TLOpacity.mjs.map +2 -2
  40. package/dist-esm/misc/TLRichText.mjs +5 -1
  41. package/dist-esm/misc/TLRichText.mjs.map +2 -2
  42. package/dist-esm/misc/b64Vecs.mjs +204 -0
  43. package/dist-esm/misc/b64Vecs.mjs.map +7 -0
  44. package/dist-esm/records/TLAsset.mjs.map +1 -1
  45. package/dist-esm/records/TLBinding.mjs.map +2 -2
  46. package/dist-esm/records/TLShape.mjs.map +2 -2
  47. package/dist-esm/shapes/TLArrowShape.mjs +26 -13
  48. package/dist-esm/shapes/TLArrowShape.mjs.map +2 -2
  49. package/dist-esm/shapes/TLBaseShape.mjs.map +2 -2
  50. package/dist-esm/shapes/TLDrawShape.mjs +37 -4
  51. package/dist-esm/shapes/TLDrawShape.mjs.map +2 -2
  52. package/dist-esm/shapes/TLEmbedShape.mjs +17 -0
  53. package/dist-esm/shapes/TLEmbedShape.mjs.map +2 -2
  54. package/dist-esm/shapes/TLGeoShape.mjs +12 -1
  55. package/dist-esm/shapes/TLGeoShape.mjs.map +2 -2
  56. package/dist-esm/shapes/TLHighlightShape.mjs +29 -2
  57. package/dist-esm/shapes/TLHighlightShape.mjs.map +2 -2
  58. package/dist-esm/shapes/TLNoteShape.mjs +12 -1
  59. package/dist-esm/shapes/TLNoteShape.mjs.map +2 -2
  60. package/dist-esm/shapes/TLTextShape.mjs +12 -1
  61. package/dist-esm/shapes/TLTextShape.mjs.map +2 -2
  62. package/dist-esm/store-migrations.mjs +15 -15
  63. package/dist-esm/store-migrations.mjs.map +2 -2
  64. package/package.json +8 -8
  65. package/src/__tests__/migrationTestUtils.ts +9 -3
  66. package/src/bindings/TLBaseBinding.ts +25 -14
  67. package/src/createTLSchema.ts +8 -2
  68. package/src/index.ts +9 -0
  69. package/src/migrations.test.ts +149 -1
  70. package/src/misc/TLOpacity.ts +1 -5
  71. package/src/misc/TLRichText.ts +6 -1
  72. package/src/misc/b64Vecs.ts +308 -0
  73. package/src/records/TLAsset.ts +2 -2
  74. package/src/records/TLBinding.ts +65 -23
  75. package/src/records/TLShape.ts +100 -5
  76. package/src/shapes/ShapeWithCrop.ts +2 -2
  77. package/src/shapes/TLArrowShape.ts +28 -14
  78. package/src/shapes/TLBaseShape.ts +34 -10
  79. package/src/shapes/TLDrawShape.ts +59 -12
  80. package/src/shapes/TLEmbedShape.ts +17 -0
  81. package/src/shapes/TLGeoShape.ts +14 -1
  82. package/src/shapes/TLHighlightShape.ts +37 -0
  83. package/src/shapes/TLNoteShape.ts +15 -1
  84. package/src/shapes/TLTextShape.ts +16 -2
  85. package/src/store-migrations.ts +17 -16
  86. package/src/assets/TLBookmarkAsset.test.ts +0 -96
  87. package/src/assets/TLImageAsset.test.ts +0 -213
  88. package/src/assets/TLVideoAsset.test.ts +0 -105
  89. package/src/bindings/TLArrowBinding.test.ts +0 -55
  90. package/src/misc/id-validator.test.ts +0 -50
  91. package/src/records/TLAsset.test.ts +0 -234
  92. package/src/records/TLBinding.test.ts +0 -22
  93. package/src/records/TLCamera.test.ts +0 -19
  94. package/src/records/TLDocument.test.ts +0 -35
  95. package/src/records/TLInstance.test.ts +0 -201
  96. package/src/records/TLPage.test.ts +0 -110
  97. package/src/records/TLPageState.test.ts +0 -228
  98. package/src/records/TLPointer.test.ts +0 -63
  99. package/src/records/TLPresence.test.ts +0 -190
  100. package/src/records/TLRecord.test.ts +0 -70
  101. package/src/records/TLShape.test.ts +0 -232
  102. package/src/shapes/ShapeWithCrop.test.ts +0 -18
  103. package/src/shapes/TLArrowShape.test.ts +0 -505
  104. package/src/shapes/TLBaseShape.test.ts +0 -142
  105. package/src/shapes/TLBookmarkShape.test.ts +0 -122
  106. package/src/shapes/TLDrawShape.test.ts +0 -177
  107. package/src/shapes/TLEmbedShape.test.ts +0 -286
  108. package/src/shapes/TLFrameShape.test.ts +0 -71
  109. package/src/shapes/TLGeoShape.test.ts +0 -247
  110. package/src/shapes/TLGroupShape.test.ts +0 -59
  111. package/src/shapes/TLHighlightShape.test.ts +0 -325
  112. package/src/shapes/TLImageShape.test.ts +0 -534
  113. package/src/shapes/TLLineShape.test.ts +0 -269
  114. package/src/shapes/TLNoteShape.test.ts +0 -1568
  115. package/src/shapes/TLTextShape.test.ts +0 -407
  116. package/src/shapes/TLVideoShape.test.ts +0 -112
  117. package/src/styles/TLColorStyle.test.ts +0 -439
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/misc/TLOpacity.ts"],
4
- "sourcesContent": ["import { T } from '@tldraw/validate'\n\n/**\n * A type representing opacity values in tldraw.\n *\n * Opacity values are numbers between 0 and 1, where 0 is fully transparent\n * and 1 is fully opaque. This type is used throughout the editor to control\n * the transparency of shapes, UI elements, and other visual components.\n *\n * @example\n * ```ts\n * const fullyOpaque: TLOpacityType = 1.0\n * const halfTransparent: TLOpacityType = 0.5\n * const fullyTransparent: TLOpacityType = 0.0\n * const quarterOpaque: TLOpacityType = 0.25\n * ```\n *\n * @public\n */\nexport type TLOpacityType = number\n\n/**\n * A validator for opacity values.\n *\n * This validator ensures that opacity values are numbers between 0 and 1 (inclusive).\n * Values outside this range will cause a validation error. The validator provides\n * runtime type checking for opacity properties throughout the editor.\n *\n * @param n - The number to validate as an opacity value\n * @throws T.ValidationError When the value is not between 0 and 1\n *\n * @example\n * ```ts\n * import { opacityValidator } from '@tldraw/tlschema'\n *\n * // Valid opacity values\n * try {\n * const validOpacity1 = opacityValidator.validate(0.5) // \u2713\n * const validOpacity2 = opacityValidator.validate(1.0) // \u2713\n * const validOpacity3 = opacityValidator.validate(0.0) // \u2713\n * } catch (error) {\n * console.error('Validation failed:', error.message)\n * }\n *\n * // Invalid opacity values\n * try {\n * opacityValidator.validate(-0.1) // \u2717 Throws error\n * opacityValidator.validate(1.5) // \u2717 Throws error\n * } catch (error) {\n * console.error('Invalid opacity:', error.message)\n * }\n * ```\n *\n * @public\n */\nexport const opacityValidator = T.number.check((n) => {\n\tif (n < 0 || n > 1) {\n\t\tthrow new T.ValidationError('Opacity must be between 0 and 1')\n\t}\n})\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAkB;AAuDX,MAAM,mBAAmB,kBAAE,OAAO,MAAM,CAAC,MAAM;AACrD,MAAI,IAAI,KAAK,IAAI,GAAG;AACnB,UAAM,IAAI,kBAAE,gBAAgB,iCAAiC;AAAA,EAC9D;AACD,CAAC;",
4
+ "sourcesContent": ["import { T } from '@tldraw/validate'\n\n/**\n * A type representing opacity values in tldraw.\n *\n * Opacity values are numbers between 0 and 1, where 0 is fully transparent\n * and 1 is fully opaque. This type is used throughout the editor to control\n * the transparency of shapes, UI elements, and other visual components.\n *\n * @example\n * ```ts\n * const fullyOpaque: TLOpacityType = 1.0\n * const halfTransparent: TLOpacityType = 0.5\n * const fullyTransparent: TLOpacityType = 0.0\n * const quarterOpaque: TLOpacityType = 0.25\n * ```\n *\n * @public\n */\nexport type TLOpacityType = number\n\n/**\n * A validator for opacity values.\n *\n * This validator ensures that opacity values are numbers between 0 and 1 (inclusive).\n * Values outside this range will cause a validation error. The validator provides\n * runtime type checking for opacity properties throughout the editor.\n *\n * @param n - The number to validate as an opacity value\n * @throws T.ValidationError When the value is not between 0 and 1\n *\n * @example\n * ```ts\n * import { opacityValidator } from '@tldraw/tlschema'\n *\n * // Valid opacity values\n * try {\n * const validOpacity1 = opacityValidator.validate(0.5) // \u2713\n * const validOpacity2 = opacityValidator.validate(1.0) // \u2713\n * const validOpacity3 = opacityValidator.validate(0.0) // \u2713\n * } catch (error) {\n * console.error('Validation failed:', error.message)\n * }\n *\n * // Invalid opacity values\n * try {\n * opacityValidator.validate(-0.1) // \u2717 Throws error\n * opacityValidator.validate(1.5) // \u2717 Throws error\n * } catch (error) {\n * console.error('Invalid opacity:', error.message)\n * }\n * ```\n *\n * @public\n */\nexport const opacityValidator = T.unitInterval\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAkB;AAuDX,MAAM,mBAAmB,kBAAE;",
6
6
  "names": []
7
7
  }
@@ -23,7 +23,11 @@ __export(TLRichText_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(TLRichText_exports);
25
25
  var import_validate = require("@tldraw/validate");
26
- const richTextValidator = import_validate.T.object({ type: import_validate.T.string, content: import_validate.T.arrayOf(import_validate.T.unknown) });
26
+ const richTextValidator = import_validate.T.object({
27
+ type: import_validate.T.string,
28
+ content: import_validate.T.arrayOf(import_validate.T.unknown),
29
+ attrs: import_validate.T.any.optional()
30
+ });
27
31
  function toRichText(text) {
28
32
  const lines = text.split("\n");
29
33
  const content = lines.map((text2) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/misc/TLRichText.ts"],
4
- "sourcesContent": ["import { T } from '@tldraw/validate'\n\n/**\n * Validator for TLRichText objects that ensures they have the correct structure\n * for document-based rich text content. Validates a document with a type field\n * and an array of content blocks.\n *\n * @public\n * @example\n * ```ts\n * const richText = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Hello' }] }] }\n * const isValid = richTextValidator.check(richText) // true\n * ```\n */\nexport const richTextValidator = T.object({ type: T.string, content: T.arrayOf(T.unknown) })\n\n/**\n * Type representing rich text content in tldraw. Rich text follows a document-based\n * structure with a root document containing an array of content blocks (paragraphs,\n * text nodes, etc.). This enables formatted text with support for multiple paragraphs,\n * styling, and other rich content.\n *\n * @public\n * @example\n * ```ts\n * const richText: TLRichText = {\n * type: 'doc',\n * content: [\n * {\n * type: 'paragraph',\n * content: [{ type: 'text', text: 'Hello world!' }]\n * }\n * ]\n * }\n * ```\n */\nexport type TLRichText = T.TypeOf<typeof richTextValidator>\n\n/**\n * Converts a plain text string into a TLRichText object. Each line of the input\n * text becomes a separate paragraph in the rich text document. Empty lines are\n * preserved as empty paragraphs to maintain the original text structure.\n *\n * @param text - The plain text string to convert to rich text\n * @returns A TLRichText object with the text content structured as paragraphs\n * @public\n * @example\n * ```ts\n * const richText = toRichText('Hello\\nWorld')\n * // Returns:\n * // {\n * // type: 'doc',\n * // content: [\n * // { type: 'paragraph', content: [{ type: 'text', text: 'Hello' }] },\n * // { type: 'paragraph', content: [{ type: 'text', text: 'World' }] }\n * // ]\n * // }\n *\n * const emptyLine = toRichText('Line 1\\n\\nLine 3')\n * // Creates three paragraphs, with the middle one being empty\n * ```\n */\nexport function toRichText(text: string): TLRichText {\n\tconst lines = text.split('\\n')\n\tconst content = lines.map((text) => {\n\t\tif (!text) {\n\t\t\treturn {\n\t\t\t\ttype: 'paragraph',\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\ttype: 'paragraph',\n\t\t\tcontent: [{ type: 'text', text }],\n\t\t}\n\t})\n\n\treturn {\n\t\ttype: 'doc',\n\t\tcontent,\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAkB;AAcX,MAAM,oBAAoB,kBAAE,OAAO,EAAE,MAAM,kBAAE,QAAQ,SAAS,kBAAE,QAAQ,kBAAE,OAAO,EAAE,CAAC;AAgDpF,SAAS,WAAW,MAA0B;AACpD,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,UAAU,MAAM,IAAI,CAACA,UAAS;AACnC,QAAI,CAACA,OAAM;AACV,aAAO;AAAA,QACN,MAAM;AAAA,MACP;AAAA,IACD;AAEA,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAAA,MAAK,CAAC;AAAA,IACjC;AAAA,EACD,CAAC;AAED,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["import { T } from '@tldraw/validate'\n\n/**\n * Validator for TLRichText objects that ensures they have the correct structure\n * for document-based rich text content. Validates a document with a type field\n * and an array of content blocks.\n *\n * @public\n * @example\n * ```ts\n * const richText = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Hello' }] }] }\n * const isValid = richTextValidator.check(richText) // true\n * ```\n */\n\nexport const richTextValidator = T.object({\n\ttype: T.string,\n\tcontent: T.arrayOf(T.unknown),\n\tattrs: T.any.optional(),\n})\n\n/**\n * Type representing rich text content in tldraw. Rich text follows a document-based\n * structure with a root document containing an array of content blocks (paragraphs,\n * text nodes, etc.). This enables formatted text with support for multiple paragraphs,\n * styling, and other rich content.\n *\n * @public\n * @example\n * ```ts\n * const richText: TLRichText = {\n * type: 'doc',\n * content: [\n * {\n * type: 'paragraph',\n * content: [{ type: 'text', text: 'Hello world!' }]\n * }\n * ]\n * }\n * ```\n */\nexport type TLRichText = T.TypeOf<typeof richTextValidator>\n\n/**\n * Converts a plain text string into a TLRichText object. Each line of the input\n * text becomes a separate paragraph in the rich text document. Empty lines are\n * preserved as empty paragraphs to maintain the original text structure.\n *\n * @param text - The plain text string to convert to rich text\n * @returns A TLRichText object with the text content structured as paragraphs\n * @public\n * @example\n * ```ts\n * const richText = toRichText('Hello\\nWorld')\n * // Returns:\n * // {\n * // type: 'doc',\n * // content: [\n * // { type: 'paragraph', content: [{ type: 'text', text: 'Hello' }] },\n * // { type: 'paragraph', content: [{ type: 'text', text: 'World' }] }\n * // ]\n * // }\n *\n * const emptyLine = toRichText('Line 1\\n\\nLine 3')\n * // Creates three paragraphs, with the middle one being empty\n * ```\n */\nexport function toRichText(text: string): TLRichText {\n\tconst lines = text.split('\\n')\n\tconst content = lines.map((text) => {\n\t\tif (!text) {\n\t\t\treturn {\n\t\t\t\ttype: 'paragraph',\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\ttype: 'paragraph',\n\t\t\tcontent: [{ type: 'text', text }],\n\t\t}\n\t})\n\n\treturn {\n\t\ttype: 'doc',\n\t\tcontent,\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAkB;AAeX,MAAM,oBAAoB,kBAAE,OAAO;AAAA,EACzC,MAAM,kBAAE;AAAA,EACR,SAAS,kBAAE,QAAQ,kBAAE,OAAO;AAAA,EAC5B,OAAO,kBAAE,IAAI,SAAS;AACvB,CAAC;AAgDM,SAAS,WAAW,MAA0B;AACpD,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,UAAU,MAAM,IAAI,CAACA,UAAS;AACnC,QAAI,CAACA,OAAM;AACV,aAAO;AAAA,QACN,MAAM;AAAA,MACP;AAAA,IACD;AAEA,WAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAAA,MAAK,CAAC;AAAA,IACjC;AAAA,EACD,CAAC;AAED,SAAO;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD;AACD;",
6
6
  "names": ["text"]
7
7
  }
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var b64Vecs_exports = {};
20
+ __export(b64Vecs_exports, {
21
+ b64Vecs: () => b64Vecs
22
+ });
23
+ module.exports = __toCommonJS(b64Vecs_exports);
24
+ const POINT_B64_LENGTH = 8;
25
+ const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
26
+ const B64_LOOKUP = new Uint8Array(128);
27
+ for (let i = 0; i < 64; i++) {
28
+ B64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i;
29
+ }
30
+ const POW2 = new Float64Array(31);
31
+ for (let i = 0; i < 31; i++) {
32
+ POW2[i] = Math.pow(2, i - 15);
33
+ }
34
+ const POW2_SUBNORMAL = Math.pow(2, -14) / 1024;
35
+ const MANTISSA = new Float64Array(1024);
36
+ for (let i = 0; i < 1024; i++) {
37
+ MANTISSA[i] = 1 + i / 1024;
38
+ }
39
+ function uint16ArrayToBase64(uint16Array) {
40
+ const uint8Array = new Uint8Array(
41
+ uint16Array.buffer,
42
+ uint16Array.byteOffset,
43
+ uint16Array.byteLength
44
+ );
45
+ let result = "";
46
+ for (let i = 0; i < uint8Array.length; i += 3) {
47
+ const byte1 = uint8Array[i];
48
+ const byte2 = uint8Array[i + 1];
49
+ const byte3 = uint8Array[i + 2];
50
+ const bitmap = byte1 << 16 | byte2 << 8 | byte3;
51
+ result += BASE64_CHARS[bitmap >> 18 & 63] + BASE64_CHARS[bitmap >> 12 & 63] + BASE64_CHARS[bitmap >> 6 & 63] + BASE64_CHARS[bitmap & 63];
52
+ }
53
+ return result;
54
+ }
55
+ function base64ToUint16Array(base64) {
56
+ const numBytes = Math.floor(base64.length * 3 / 4);
57
+ const bytes = new Uint8Array(numBytes);
58
+ let byteIndex = 0;
59
+ for (let i = 0; i < base64.length; i += 4) {
60
+ const c0 = B64_LOOKUP[base64.charCodeAt(i)];
61
+ const c1 = B64_LOOKUP[base64.charCodeAt(i + 1)];
62
+ const c2 = B64_LOOKUP[base64.charCodeAt(i + 2)];
63
+ const c3 = B64_LOOKUP[base64.charCodeAt(i + 3)];
64
+ const bitmap = c0 << 18 | c1 << 12 | c2 << 6 | c3;
65
+ bytes[byteIndex++] = bitmap >> 16 & 255;
66
+ bytes[byteIndex++] = bitmap >> 8 & 255;
67
+ bytes[byteIndex++] = bitmap & 255;
68
+ }
69
+ return new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);
70
+ }
71
+ function float16BitsToNumber(bits) {
72
+ const sign = bits >> 15;
73
+ const exp = bits >> 10 & 31;
74
+ const frac = bits & 1023;
75
+ if (exp === 0) {
76
+ return sign ? -frac * POW2_SUBNORMAL : frac * POW2_SUBNORMAL;
77
+ }
78
+ if (exp === 31) {
79
+ return frac ? NaN : sign ? -Infinity : Infinity;
80
+ }
81
+ const magnitude = POW2[exp] * MANTISSA[frac];
82
+ return sign ? -magnitude : magnitude;
83
+ }
84
+ function numberToFloat16Bits(value) {
85
+ if (value === 0) return Object.is(value, -0) ? 32768 : 0;
86
+ if (!Number.isFinite(value)) {
87
+ if (Number.isNaN(value)) return 32256;
88
+ return value > 0 ? 31744 : 64512;
89
+ }
90
+ const sign = value < 0 ? 1 : 0;
91
+ value = Math.abs(value);
92
+ const exp = Math.floor(Math.log2(value));
93
+ let expBiased = exp + 15;
94
+ if (expBiased >= 31) {
95
+ return sign << 15 | 31744;
96
+ }
97
+ if (expBiased <= 0) {
98
+ const frac2 = Math.round(value * Math.pow(2, 14) * 1024);
99
+ return sign << 15 | frac2 & 1023;
100
+ }
101
+ const mantissa = value / Math.pow(2, exp) - 1;
102
+ let frac = Math.round(mantissa * 1024);
103
+ if (frac >= 1024) {
104
+ frac = 0;
105
+ expBiased++;
106
+ if (expBiased >= 31) {
107
+ return sign << 15 | 31744;
108
+ }
109
+ }
110
+ return sign << 15 | expBiased << 10 | frac;
111
+ }
112
+ class b64Vecs {
113
+ /**
114
+ * Encode a single point (x, y, z) to 8 base64 characters.
115
+ * Each coordinate is encoded as a Float16 value, resulting in 6 bytes total.
116
+ *
117
+ * @param x - The x coordinate
118
+ * @param y - The y coordinate
119
+ * @param z - The z coordinate
120
+ * @returns An 8-character base64 string representing the point
121
+ */
122
+ static encodePoint(x, y, z) {
123
+ const xBits = numberToFloat16Bits(x);
124
+ const yBits = numberToFloat16Bits(y);
125
+ const zBits = numberToFloat16Bits(z);
126
+ const b0 = xBits & 255;
127
+ const b1 = xBits >> 8 & 255;
128
+ const b2 = yBits & 255;
129
+ const b3 = yBits >> 8 & 255;
130
+ const b4 = zBits & 255;
131
+ const b5 = zBits >> 8 & 255;
132
+ const bitmap1 = b0 << 16 | b1 << 8 | b2;
133
+ const bitmap2 = b3 << 16 | b4 << 8 | b5;
134
+ return BASE64_CHARS[bitmap1 >> 18 & 63] + BASE64_CHARS[bitmap1 >> 12 & 63] + BASE64_CHARS[bitmap1 >> 6 & 63] + BASE64_CHARS[bitmap1 & 63] + BASE64_CHARS[bitmap2 >> 18 & 63] + BASE64_CHARS[bitmap2 >> 12 & 63] + BASE64_CHARS[bitmap2 >> 6 & 63] + BASE64_CHARS[bitmap2 & 63];
135
+ }
136
+ /**
137
+ * Convert an array of VecModels to a base64 string for compact storage.
138
+ * Uses Float16 encoding for each coordinate (x, y, z). If a point's z value is
139
+ * undefined, it defaults to 0.5.
140
+ *
141
+ * @param points - An array of VecModel objects to encode
142
+ * @returns A base64-encoded string containing all points
143
+ */
144
+ static encodePoints(points) {
145
+ const uint16s = new Uint16Array(points.length * 3);
146
+ for (let i = 0; i < points.length; i++) {
147
+ const p = points[i];
148
+ uint16s[i * 3] = numberToFloat16Bits(p.x);
149
+ uint16s[i * 3 + 1] = numberToFloat16Bits(p.y);
150
+ uint16s[i * 3 + 2] = numberToFloat16Bits(p.z ?? 0.5);
151
+ }
152
+ return uint16ArrayToBase64(uint16s);
153
+ }
154
+ /**
155
+ * Convert a base64 string back to an array of VecModels.
156
+ * Decodes Float16-encoded coordinates (x, y, z) from the base64 string.
157
+ *
158
+ * @param base64 - The base64-encoded string containing point data
159
+ * @returns An array of VecModel objects decoded from the string
160
+ */
161
+ static decodePoints(base64) {
162
+ const uint16s = base64ToUint16Array(base64);
163
+ const result = [];
164
+ for (let i = 0; i < uint16s.length; i += 3) {
165
+ result.push({
166
+ x: float16BitsToNumber(uint16s[i]),
167
+ y: float16BitsToNumber(uint16s[i + 1]),
168
+ z: float16BitsToNumber(uint16s[i + 2])
169
+ });
170
+ }
171
+ return result;
172
+ }
173
+ /**
174
+ * Decode a single point (8 base64 chars) starting at the given offset.
175
+ * Each point is encoded as 3 Float16 values (x, y, z) in 8 base64 characters.
176
+ *
177
+ * @param b64Points - The base64-encoded string containing point data
178
+ * @param charOffset - The character offset where the point starts (must be a multiple of 8)
179
+ * @returns A VecModel object with x, y, and z coordinates
180
+ * @internal
181
+ */
182
+ static decodePointAt(b64Points, charOffset) {
183
+ const c0 = B64_LOOKUP[b64Points.charCodeAt(charOffset)];
184
+ const c1 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 1)];
185
+ const c2 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 2)];
186
+ const c3 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 3)];
187
+ const c4 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 4)];
188
+ const c5 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 5)];
189
+ const c6 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 6)];
190
+ const c7 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 7)];
191
+ const bitmap1 = c0 << 18 | c1 << 12 | c2 << 6 | c3;
192
+ const bitmap2 = c4 << 18 | c5 << 12 | c6 << 6 | c7;
193
+ const xBits = bitmap1 >> 16 & 255 | bitmap1 & 65280;
194
+ const yBits = bitmap1 & 255 | bitmap2 >> 8 & 65280;
195
+ const zBits = bitmap2 >> 8 & 255 | bitmap2 << 8 & 65280;
196
+ return {
197
+ x: float16BitsToNumber(xBits),
198
+ y: float16BitsToNumber(yBits),
199
+ z: float16BitsToNumber(zBits)
200
+ };
201
+ }
202
+ /**
203
+ * Get the first point from a base64-encoded string of points.
204
+ *
205
+ * @param b64Points - The base64-encoded string containing point data
206
+ * @returns The first point as a VecModel, or null if the string is too short
207
+ * @public
208
+ */
209
+ static decodeFirstPoint(b64Points) {
210
+ if (b64Points.length < POINT_B64_LENGTH) return null;
211
+ return b64Vecs.decodePointAt(b64Points, 0);
212
+ }
213
+ /**
214
+ * Get the last point from a base64-encoded string of points.
215
+ *
216
+ * @param b64Points - The base64-encoded string containing point data
217
+ * @returns The last point as a VecModel, or null if the string is too short
218
+ */
219
+ static decodeLastPoint(b64Points) {
220
+ if (b64Points.length < POINT_B64_LENGTH) return null;
221
+ return b64Vecs.decodePointAt(b64Points, b64Points.length - POINT_B64_LENGTH);
222
+ }
223
+ }
224
+ //# sourceMappingURL=b64Vecs.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/misc/b64Vecs.ts"],
4
+ "sourcesContent": ["import { VecModel } from './geometry-types'\n\n// Each point = 3 Float16s = 6 bytes = 8 base64 chars\nconst POINT_B64_LENGTH = 8\n\n// O(1) lookup table for base64 decoding (maps char code -> 6-bit value)\nconst BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nconst B64_LOOKUP = new Uint8Array(128)\nfor (let i = 0; i < 64; i++) {\n\tB64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i\n}\n\n// Precomputed powers of 2 for Float16 exponents (exp - 15, so indices 0-30 map to 2^-15 to 2^15)\nconst POW2 = new Float64Array(31)\nfor (let i = 0; i < 31; i++) {\n\tPOW2[i] = Math.pow(2, i - 15)\n}\nconst POW2_SUBNORMAL = Math.pow(2, -14) / 1024 // For subnormal numbers\n\n// Precomputed mantissa values: 1 + frac/1024 for all 1024 possible frac values\n// Avoids division in hot path\nconst MANTISSA = new Float64Array(1024)\nfor (let i = 0; i < 1024; i++) {\n\tMANTISSA[i] = 1 + i / 1024\n}\n\n/**\n * Convert a Uint16Array (containing Float16 bits) to base64.\n * Processes bytes in groups of 3 to produce 4 base64 characters.\n *\n * @internal\n */\nfunction uint16ArrayToBase64(uint16Array: Uint16Array): string {\n\tconst uint8Array = new Uint8Array(\n\t\tuint16Array.buffer,\n\t\tuint16Array.byteOffset,\n\t\tuint16Array.byteLength\n\t)\n\tlet result = ''\n\n\t// Process bytes in groups of 3 -> 4 base64 chars\n\tfor (let i = 0; i < uint8Array.length; i += 3) {\n\t\tconst byte1 = uint8Array[i]\n\t\tconst byte2 = uint8Array[i + 1] // Always exists for our use case (multiple of 6 bytes)\n\t\tconst byte3 = uint8Array[i + 2]\n\n\t\tconst bitmap = (byte1 << 16) | (byte2 << 8) | byte3\n\t\tresult +=\n\t\t\tBASE64_CHARS[(bitmap >> 18) & 63] +\n\t\t\tBASE64_CHARS[(bitmap >> 12) & 63] +\n\t\t\tBASE64_CHARS[(bitmap >> 6) & 63] +\n\t\t\tBASE64_CHARS[bitmap & 63]\n\t}\n\n\treturn result\n}\n\n/**\n * Convert a base64 string to Uint16Array containing Float16 bits.\n * The base64 string must have a length that is a multiple of 4.\n *\n * @param base64 - The base64-encoded string to decode\n * @returns A Uint16Array containing the decoded Float16 bit values\n * @public\n */\nfunction base64ToUint16Array(base64: string): Uint16Array {\n\t// Calculate exact number of bytes (4 base64 chars = 3 bytes)\n\tconst numBytes = Math.floor((base64.length * 3) / 4)\n\tconst bytes = new Uint8Array(numBytes)\n\tlet byteIndex = 0\n\n\t// Process in groups of 4 base64 characters\n\tfor (let i = 0; i < base64.length; i += 4) {\n\t\tconst c0 = B64_LOOKUP[base64.charCodeAt(i)]\n\t\tconst c1 = B64_LOOKUP[base64.charCodeAt(i + 1)]\n\t\tconst c2 = B64_LOOKUP[base64.charCodeAt(i + 2)]\n\t\tconst c3 = B64_LOOKUP[base64.charCodeAt(i + 3)]\n\n\t\tconst bitmap = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3\n\n\t\tbytes[byteIndex++] = (bitmap >> 16) & 255\n\t\tbytes[byteIndex++] = (bitmap >> 8) & 255\n\t\tbytes[byteIndex++] = bitmap & 255\n\t}\n\n\treturn new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2)\n}\n\n/**\n * Convert Float16 bits to a number using optimized lookup tables.\n * Handles normal numbers, subnormal numbers, zero, infinity, and NaN.\n *\n * @param bits - The 16-bit Float16 value to decode\n * @returns The decoded number value\n */\nfunction float16BitsToNumber(bits: number): number {\n\tconst sign = bits >> 15\n\tconst exp = (bits >> 10) & 0x1f\n\tconst frac = bits & 0x3ff\n\n\tif (exp === 0) {\n\t\t// Subnormal or zero - rare case\n\t\treturn sign ? -frac * POW2_SUBNORMAL : frac * POW2_SUBNORMAL\n\t}\n\tif (exp === 31) {\n\t\t// Infinity or NaN - very rare\n\t\treturn frac ? NaN : sign ? -Infinity : Infinity\n\t}\n\t// Normal case - two table lookups, one multiply, no division\n\tconst magnitude = POW2[exp] * MANTISSA[frac]\n\treturn sign ? -magnitude : magnitude\n}\n\n/**\n * Convert a number to Float16 bits.\n * Handles normal numbers, subnormal numbers, zero, infinity, and NaN.\n *\n * @param value - The number to encode as Float16\n * @returns The 16-bit Float16 representation of the number\n * @internal\n */\nfunction numberToFloat16Bits(value: number): number {\n\tif (value === 0) return Object.is(value, -0) ? 0x8000 : 0\n\tif (!Number.isFinite(value)) {\n\t\tif (Number.isNaN(value)) return 0x7e00\n\t\treturn value > 0 ? 0x7c00 : 0xfc00\n\t}\n\n\tconst sign = value < 0 ? 1 : 0\n\tvalue = Math.abs(value)\n\n\t// Find exponent and mantissa\n\tconst exp = Math.floor(Math.log2(value))\n\tlet expBiased = exp + 15\n\n\tif (expBiased >= 31) {\n\t\t// Overflow to infinity\n\t\treturn (sign << 15) | 0x7c00\n\t}\n\tif (expBiased <= 0) {\n\t\t// Subnormal or underflow\n\t\tconst frac = Math.round(value * Math.pow(2, 14) * 1024)\n\t\treturn (sign << 15) | (frac & 0x3ff)\n\t}\n\n\t// Normal number\n\tconst mantissa = value / Math.pow(2, exp) - 1\n\tlet frac = Math.round(mantissa * 1024)\n\n\t// Handle rounding overflow: if frac rounds to 1024, increment exponent\n\tif (frac >= 1024) {\n\t\tfrac = 0\n\t\texpBiased++\n\t\tif (expBiased >= 31) {\n\t\t\t// Overflow to infinity\n\t\t\treturn (sign << 15) | 0x7c00\n\t\t}\n\t}\n\n\treturn (sign << 15) | (expBiased << 10) | frac\n}\n\n/**\n * Utilities for encoding and decoding points using base64 and Float16 encoding.\n * Provides functions for converting between VecModel arrays and compact base64 strings,\n * as well as individual point encoding/decoding operations.\n *\n * @public\n */\nexport class b64Vecs {\n\t/**\n\t * Encode a single point (x, y, z) to 8 base64 characters.\n\t * Each coordinate is encoded as a Float16 value, resulting in 6 bytes total.\n\t *\n\t * @param x - The x coordinate\n\t * @param y - The y coordinate\n\t * @param z - The z coordinate\n\t * @returns An 8-character base64 string representing the point\n\t */\n\tstatic encodePoint(x: number, y: number, z: number): string {\n\t\tconst xBits = numberToFloat16Bits(x)\n\t\tconst yBits = numberToFloat16Bits(y)\n\t\tconst zBits = numberToFloat16Bits(z)\n\n\t\t// Convert Float16 bits to 6 bytes (little-endian)\n\t\tconst b0 = xBits & 0xff\n\t\tconst b1 = (xBits >> 8) & 0xff\n\t\tconst b2 = yBits & 0xff\n\t\tconst b3 = (yBits >> 8) & 0xff\n\t\tconst b4 = zBits & 0xff\n\t\tconst b5 = (zBits >> 8) & 0xff\n\n\t\t// Convert 6 bytes to 8 base64 chars\n\t\tconst bitmap1 = (b0 << 16) | (b1 << 8) | b2\n\t\tconst bitmap2 = (b3 << 16) | (b4 << 8) | b5\n\n\t\treturn (\n\t\t\tBASE64_CHARS[(bitmap1 >> 18) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap1 >> 12) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap1 >> 6) & 0x3f] +\n\t\t\tBASE64_CHARS[bitmap1 & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap2 >> 18) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap2 >> 12) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap2 >> 6) & 0x3f] +\n\t\t\tBASE64_CHARS[bitmap2 & 0x3f]\n\t\t)\n\t}\n\n\t/**\n\t * Convert an array of VecModels to a base64 string for compact storage.\n\t * Uses Float16 encoding for each coordinate (x, y, z). If a point's z value is\n\t * undefined, it defaults to 0.5.\n\t *\n\t * @param points - An array of VecModel objects to encode\n\t * @returns A base64-encoded string containing all points\n\t */\n\tstatic encodePoints(points: VecModel[]): string {\n\t\tconst uint16s = new Uint16Array(points.length * 3)\n\t\tfor (let i = 0; i < points.length; i++) {\n\t\t\tconst p = points[i]\n\t\t\tuint16s[i * 3] = numberToFloat16Bits(p.x)\n\t\t\tuint16s[i * 3 + 1] = numberToFloat16Bits(p.y)\n\t\t\tuint16s[i * 3 + 2] = numberToFloat16Bits(p.z ?? 0.5)\n\t\t}\n\t\treturn uint16ArrayToBase64(uint16s)\n\t}\n\n\t/**\n\t * Convert a base64 string back to an array of VecModels.\n\t * Decodes Float16-encoded coordinates (x, y, z) from the base64 string.\n\t *\n\t * @param base64 - The base64-encoded string containing point data\n\t * @returns An array of VecModel objects decoded from the string\n\t */\n\tstatic decodePoints(base64: string): VecModel[] {\n\t\tconst uint16s = base64ToUint16Array(base64)\n\t\tconst result: VecModel[] = []\n\t\tfor (let i = 0; i < uint16s.length; i += 3) {\n\t\t\tresult.push({\n\t\t\t\tx: float16BitsToNumber(uint16s[i]),\n\t\t\t\ty: float16BitsToNumber(uint16s[i + 1]),\n\t\t\t\tz: float16BitsToNumber(uint16s[i + 2]),\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Decode a single point (8 base64 chars) starting at the given offset.\n\t * Each point is encoded as 3 Float16 values (x, y, z) in 8 base64 characters.\n\t *\n\t * @param b64Points - The base64-encoded string containing point data\n\t * @param charOffset - The character offset where the point starts (must be a multiple of 8)\n\t * @returns A VecModel object with x, y, and z coordinates\n\t * @internal\n\t */\n\tstatic decodePointAt(b64Points: string, charOffset: number): VecModel {\n\t\t// Decode 8 base64 chars -> 6 bytes -> 3 Float16s using O(1) lookup\n\t\tconst c0 = B64_LOOKUP[b64Points.charCodeAt(charOffset)]\n\t\tconst c1 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 1)]\n\t\tconst c2 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 2)]\n\t\tconst c3 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 3)]\n\t\tconst c4 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 4)]\n\t\tconst c5 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 5)]\n\t\tconst c6 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 6)]\n\t\tconst c7 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 7)]\n\n\t\t// 4 base64 chars -> 24 bits -> 3 bytes\n\t\tconst bitmap1 = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3\n\t\tconst bitmap2 = (c4 << 18) | (c5 << 12) | (c6 << 6) | c7\n\n\t\t// Extract Float16 bits directly (little-endian byte order)\n\t\t// bitmap1 = [byte0:8][byte1:8][byte2:8], bitmap2 = [byte3:8][byte4:8][byte5:8]\n\t\t// xBits = byte0 | (byte1 << 8), yBits = byte2 | (byte3 << 8), zBits = byte4 | (byte5 << 8)\n\t\tconst xBits = ((bitmap1 >> 16) & 0xff) | (bitmap1 & 0xff00)\n\t\tconst yBits = (bitmap1 & 0xff) | ((bitmap2 >> 8) & 0xff00)\n\t\tconst zBits = ((bitmap2 >> 8) & 0xff) | ((bitmap2 << 8) & 0xff00)\n\n\t\treturn {\n\t\t\tx: float16BitsToNumber(xBits),\n\t\t\ty: float16BitsToNumber(yBits),\n\t\t\tz: float16BitsToNumber(zBits),\n\t\t}\n\t}\n\n\t/**\n\t * Get the first point from a base64-encoded string of points.\n\t *\n\t * @param b64Points - The base64-encoded string containing point data\n\t * @returns The first point as a VecModel, or null if the string is too short\n\t * @public\n\t */\n\tstatic decodeFirstPoint(b64Points: string): VecModel | null {\n\t\tif (b64Points.length < POINT_B64_LENGTH) return null\n\t\treturn b64Vecs.decodePointAt(b64Points, 0)\n\t}\n\n\t/**\n\t * Get the last point from a base64-encoded string of points.\n\t *\n\t * @param b64Points - The base64-encoded string containing point data\n\t * @returns The last point as a VecModel, or null if the string is too short\n\t */\n\tstatic decodeLastPoint(b64Points: string): VecModel | null {\n\t\tif (b64Points.length < POINT_B64_LENGTH) return null\n\t\treturn b64Vecs.decodePointAt(b64Points, b64Points.length - POINT_B64_LENGTH)\n\t}\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["frac"]
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/records/TLAsset.ts"],
4
- "sourcesContent": ["import {\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLBaseAsset } from '../assets/TLBaseAsset'\nimport { bookmarkAssetValidator, TLBookmarkAsset } from '../assets/TLBookmarkAsset'\nimport { imageAssetValidator, TLImageAsset } from '../assets/TLImageAsset'\nimport { TLVideoAsset, videoAssetValidator } from '../assets/TLVideoAsset'\nimport { TLShape } from './TLShape'\n\n/**\n * Union type representing all possible asset types in tldraw.\n * Assets represent external resources like images, videos, or bookmarks that can be referenced by shapes.\n *\n * @example\n * ```ts\n * const imageAsset: TLAsset = {\n * id: 'asset:image123',\n * typeName: 'asset',\n * type: 'image',\n * props: {\n * src: 'https://example.com/image.jpg',\n * w: 800,\n * h: 600,\n * mimeType: 'image/jpeg',\n * isAnimated: false\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport type TLAsset = TLImageAsset | TLVideoAsset | TLBookmarkAsset\n\n/**\n * Validator for TLAsset records that ensures runtime type safety.\n * Uses a discriminated union based on the 'type' field to validate different asset types.\n *\n * @example\n * ```ts\n * // Validation happens automatically when assets are stored\n * try {\n * const validatedAsset = assetValidator.validate(assetData)\n * store.put([validatedAsset])\n * } catch (error) {\n * console.error('Asset validation failed:', error.message)\n * }\n * ```\n *\n * @public\n */\nexport const assetValidator: T.Validator<TLAsset> = T.model(\n\t'asset',\n\tT.union('type', {\n\t\timage: imageAssetValidator,\n\t\tvideo: videoAssetValidator,\n\t\tbookmark: bookmarkAssetValidator,\n\t})\n)\n\n/**\n * Migration version identifiers for asset record schema evolution.\n * Each version represents a breaking change that requires data migration.\n *\n * @example\n * ```ts\n * // Check if a migration is needed\n * const needsMigration = currentVersion < assetVersions.AddMeta\n * ```\n *\n * @public\n */\nexport const assetVersions = createMigrationIds('com.tldraw.asset', {\n\tAddMeta: 1,\n} as const)\n\n/**\n * Migration sequence for evolving asset record structure over time.\n * Handles converting asset records from older schema versions to current format.\n *\n * @example\n * ```ts\n * // Migration is applied automatically when loading old documents\n * const migratedStore = migrator.migrateStoreSnapshot({\n * schema: oldSchema,\n * store: oldStoreSnapshot\n * })\n * ```\n *\n * @public\n */\nexport const assetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset',\n\trecordType: 'asset',\n\tsequence: [\n\t\t{\n\t\t\tid: assetVersions.AddMeta,\n\t\t\tup: (record) => {\n\t\t\t\t;(record as any).meta = {}\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * Partial type for TLAsset allowing optional properties except id and type.\n * Useful for creating or updating assets where not all properties need to be specified.\n *\n * @example\n * ```ts\n * // Create a partial asset for updating\n * const partialAsset: TLAssetPartial<TLImageAsset> = {\n * id: 'asset:image123',\n * type: 'image',\n * props: {\n * w: 800 // Only updating width\n * }\n * }\n *\n * // Use in asset updates\n * editor.updateAssets([partialAsset])\n * ```\n *\n * @public\n */\nexport type TLAssetPartial<T extends TLAsset = TLAsset> = T extends T\n\t? {\n\t\t\tid: TLAssetId\n\t\t\ttype: T['type']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t} & Partial<Omit<T, 'type' | 'id' | 'props' | 'meta'>>\n\t: never\n\n/**\n * Record type definition for TLAsset with validation and default properties.\n * Configures assets as document-scoped records that persist across sessions.\n *\n * @example\n * ```ts\n * // Create a new asset record\n * const assetRecord = AssetRecordType.create({\n * id: 'asset:image123',\n * type: 'image',\n * props: {\n * src: 'https://example.com/image.jpg',\n * w: 800,\n * h: 600,\n * mimeType: 'image/jpeg',\n * isAnimated: false\n * }\n * })\n *\n * // Store the asset\n * store.put([assetRecord])\n * ```\n *\n * @public\n */\nexport const AssetRecordType = createRecordType<TLAsset>('asset', {\n\tvalidator: assetValidator,\n\tscope: 'document',\n}).withDefaultProperties(() => ({\n\tmeta: {},\n}))\n\n/**\n * Branded string type for asset record identifiers.\n * Prevents mixing asset IDs with other types of record IDs at compile time.\n *\n * @example\n * ```ts\n * import { createAssetId } from '@tldraw/tlschema'\n *\n * // Create a new asset ID\n * const assetId: TLAssetId = createAssetId()\n *\n * // Use in asset records\n * const asset: TLAsset = {\n * id: assetId,\n * // ... other properties\n * }\n *\n * // Reference in shapes\n * const imageShape: TLImageShape = {\n * props: {\n * assetId: assetId,\n * // ... other properties\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLAssetId = RecordId<TLBaseAsset<any, any>>\n\n/**\n * Union type of all shapes that reference assets through an assetId property.\n * Includes image shapes, video shapes, and any other shapes that depend on external assets.\n *\n * @example\n * ```ts\n * // Function that works with any asset-based shape\n * function handleAssetShape(shape: TLAssetShape) {\n * const assetId = shape.props.assetId\n * if (assetId) {\n * const asset = editor.getAsset(assetId)\n * // Handle the asset...\n * }\n * }\n *\n * // Use with image or video shapes\n * const imageShape: TLImageShape = { props: { assetId: 'asset:img1' } }\n * const videoShape: TLVideoShape = { props: { assetId: 'asset:vid1' } }\n * handleAssetShape(imageShape) // Works\n * handleAssetShape(videoShape) // Works\n * ```\n *\n * @public\n */\nexport type TLAssetShape = Extract<TLShape, { props: { assetId: TLAssetId } }>\n"],
4
+ "sourcesContent": ["import {\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { TLBaseAsset } from '../assets/TLBaseAsset'\nimport { bookmarkAssetValidator, TLBookmarkAsset } from '../assets/TLBookmarkAsset'\nimport { imageAssetValidator, TLImageAsset } from '../assets/TLImageAsset'\nimport { TLVideoAsset, videoAssetValidator } from '../assets/TLVideoAsset'\nimport { ExtractShapeByProps } from './TLShape'\n\n/**\n * Union type representing all possible asset types in tldraw.\n * Assets represent external resources like images, videos, or bookmarks that can be referenced by shapes.\n *\n * @example\n * ```ts\n * const imageAsset: TLAsset = {\n * id: 'asset:image123',\n * typeName: 'asset',\n * type: 'image',\n * props: {\n * src: 'https://example.com/image.jpg',\n * w: 800,\n * h: 600,\n * mimeType: 'image/jpeg',\n * isAnimated: false\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport type TLAsset = TLImageAsset | TLVideoAsset | TLBookmarkAsset\n\n/**\n * Validator for TLAsset records that ensures runtime type safety.\n * Uses a discriminated union based on the 'type' field to validate different asset types.\n *\n * @example\n * ```ts\n * // Validation happens automatically when assets are stored\n * try {\n * const validatedAsset = assetValidator.validate(assetData)\n * store.put([validatedAsset])\n * } catch (error) {\n * console.error('Asset validation failed:', error.message)\n * }\n * ```\n *\n * @public\n */\nexport const assetValidator: T.Validator<TLAsset> = T.model(\n\t'asset',\n\tT.union('type', {\n\t\timage: imageAssetValidator,\n\t\tvideo: videoAssetValidator,\n\t\tbookmark: bookmarkAssetValidator,\n\t})\n)\n\n/**\n * Migration version identifiers for asset record schema evolution.\n * Each version represents a breaking change that requires data migration.\n *\n * @example\n * ```ts\n * // Check if a migration is needed\n * const needsMigration = currentVersion < assetVersions.AddMeta\n * ```\n *\n * @public\n */\nexport const assetVersions = createMigrationIds('com.tldraw.asset', {\n\tAddMeta: 1,\n} as const)\n\n/**\n * Migration sequence for evolving asset record structure over time.\n * Handles converting asset records from older schema versions to current format.\n *\n * @example\n * ```ts\n * // Migration is applied automatically when loading old documents\n * const migratedStore = migrator.migrateStoreSnapshot({\n * schema: oldSchema,\n * store: oldStoreSnapshot\n * })\n * ```\n *\n * @public\n */\nexport const assetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset',\n\trecordType: 'asset',\n\tsequence: [\n\t\t{\n\t\t\tid: assetVersions.AddMeta,\n\t\t\tup: (record) => {\n\t\t\t\t;(record as any).meta = {}\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * Partial type for TLAsset allowing optional properties except id and type.\n * Useful for creating or updating assets where not all properties need to be specified.\n *\n * @example\n * ```ts\n * // Create a partial asset for updating\n * const partialAsset: TLAssetPartial<TLImageAsset> = {\n * id: 'asset:image123',\n * type: 'image',\n * props: {\n * w: 800 // Only updating width\n * }\n * }\n *\n * // Use in asset updates\n * editor.updateAssets([partialAsset])\n * ```\n *\n * @public\n */\nexport type TLAssetPartial<T extends TLAsset = TLAsset> = T extends T\n\t? {\n\t\t\tid: TLAssetId\n\t\t\ttype: T['type']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t} & Partial<Omit<T, 'type' | 'id' | 'props' | 'meta'>>\n\t: never\n\n/**\n * Record type definition for TLAsset with validation and default properties.\n * Configures assets as document-scoped records that persist across sessions.\n *\n * @example\n * ```ts\n * // Create a new asset record\n * const assetRecord = AssetRecordType.create({\n * id: 'asset:image123',\n * type: 'image',\n * props: {\n * src: 'https://example.com/image.jpg',\n * w: 800,\n * h: 600,\n * mimeType: 'image/jpeg',\n * isAnimated: false\n * }\n * })\n *\n * // Store the asset\n * store.put([assetRecord])\n * ```\n *\n * @public\n */\nexport const AssetRecordType = createRecordType<TLAsset>('asset', {\n\tvalidator: assetValidator,\n\tscope: 'document',\n}).withDefaultProperties(() => ({\n\tmeta: {},\n}))\n\n/**\n * Branded string type for asset record identifiers.\n * Prevents mixing asset IDs with other types of record IDs at compile time.\n *\n * @example\n * ```ts\n * import { createAssetId } from '@tldraw/tlschema'\n *\n * // Create a new asset ID\n * const assetId: TLAssetId = createAssetId()\n *\n * // Use in asset records\n * const asset: TLAsset = {\n * id: assetId,\n * // ... other properties\n * }\n *\n * // Reference in shapes\n * const imageShape: TLImageShape = {\n * props: {\n * assetId: assetId,\n * // ... other properties\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLAssetId = RecordId<TLBaseAsset<any, any>>\n\n/**\n * Union type of all shapes that reference assets through an assetId property.\n * Includes image shapes, video shapes, and any other shapes that depend on external assets.\n *\n * @example\n * ```ts\n * // Function that works with any asset-based shape\n * function handleAssetShape(shape: TLAssetShape) {\n * const assetId = shape.props.assetId\n * if (assetId) {\n * const asset = editor.getAsset(assetId)\n * // Handle the asset...\n * }\n * }\n *\n * // Use with image or video shapes\n * const imageShape: TLImageShape = { props: { assetId: 'asset:img1' } }\n * const videoShape: TLVideoShape = { props: { assetId: 'asset:vid1' } }\n * handleAssetShape(imageShape) // Works\n * handleAssetShape(videoShape) // Works\n * ```\n *\n * @public\n */\nexport type TLAssetShape = ExtractShapeByProps<{ assetId: TLAssetId }>\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAKO;AACP,sBAAkB;AAElB,6BAAwD;AACxD,0BAAkD;AAClD,0BAAkD;AA6C3C,MAAM,iBAAuC,kBAAE;AAAA,EACrD;AAAA,EACA,kBAAE,MAAM,QAAQ;AAAA,IACf,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACX,CAAC;AACF;AAcO,MAAM,oBAAgB,iCAAmB,oBAAoB;AAAA,EACnE,SAAS;AACV,CAAU;AAiBH,MAAM,sBAAkB,4CAA8B;AAAA,EAC5D,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,IACT;AAAA,MACC,IAAI,cAAc;AAAA,MAClB,IAAI,CAAC,WAAW;AACf;AAAC,QAAC,OAAe,OAAO,CAAC;AAAA,MAC1B;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAyDM,MAAM,sBAAkB,+BAA0B,SAAS;AAAA,EACjE,WAAW;AAAA,EACX,OAAO;AACR,CAAC,EAAE,sBAAsB,OAAO;AAAA,EAC/B,MAAM,CAAC;AACR,EAAE;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/records/TLBinding.ts"],
4
- "sourcesContent": ["import {\n\tRecordId,\n\tUnknownRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n} from '@tldraw/store'\nimport { Expand, mapObjectMapValues, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { TLArrowBinding } from '../bindings/TLArrowBinding'\nimport { TLBaseBinding, createBindingValidator } from '../bindings/TLBaseBinding'\nimport { SchemaPropsInfo } from '../createTLSchema'\nimport { TLPropsMigrations } from '../recordsWithProps'\n\n/**\n * The default set of bindings that are available in the editor.\n * Currently includes only arrow bindings, but can be extended with custom bindings.\n *\n * @example\n * ```ts\n * // Arrow binding connects an arrow to shapes\n * const arrowBinding: TLDefaultBinding = {\n * id: 'binding:arrow1',\n * typeName: 'binding',\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * props: {\n * terminal: 'end',\n * normalizedAnchor: { x: 0.5, y: 0.5 },\n * isExact: false,\n * isPrecise: true\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLDefaultBinding = TLArrowBinding\n\n/**\n * A type for a binding that is available in the editor but whose type is\n * unknown\u2014either one of the editor's default bindings or else a custom binding.\n * Used internally for type-safe handling of bindings with unknown structure.\n *\n * @example\n * ```ts\n * // Function that works with any binding type\n * function processBinding(binding: TLUnknownBinding) {\n * console.log(`Processing ${binding.type} binding from ${binding.fromId} to ${binding.toId}`)\n * // Handle binding properties generically\n * }\n * ```\n *\n * @public\n */\nexport type TLUnknownBinding = TLBaseBinding<string, object>\n\n/**\n * The set of all bindings that are available in the editor, including unknown bindings.\n * Bindings represent relationships between shapes, such as arrows connecting to other shapes.\n *\n * @example\n * ```ts\n * // Check binding type and handle accordingly\n * function handleBinding(binding: TLBinding) {\n * switch (binding.type) {\n * case 'arrow':\n * // Handle arrow binding\n * break\n * default:\n * // Handle unknown custom binding\n * break\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLBinding = TLDefaultBinding | TLUnknownBinding\n\n/**\n * Type for updating existing bindings with partial properties.\n * Only the id and type are required, all other properties are optional.\n *\n * @example\n * ```ts\n * // Update arrow binding properties\n * const bindingUpdate: TLBindingUpdate<TLArrowBinding> = {\n * id: 'binding:arrow1',\n * type: 'arrow',\n * props: {\n * normalizedAnchor: { x: 0.7, y: 0.3 } // Only update anchor position\n * }\n * }\n *\n * editor.updateBindings([bindingUpdate])\n * ```\n *\n * @public\n */\nexport type TLBindingUpdate<T extends TLBinding = TLBinding> = Expand<{\n\tid: TLBindingId\n\ttype: T['type']\n\ttypeName?: T['typeName']\n\tfromId?: T['fromId']\n\ttoId?: T['toId']\n\tprops?: Partial<T['props']>\n\tmeta?: Partial<T['meta']>\n}>\n\n/**\n * Type for creating new bindings with required fromId and toId.\n * The id is optional and will be generated if not provided.\n *\n * @example\n * ```ts\n * // Create a new arrow binding\n * const newBinding: TLBindingCreate<TLArrowBinding> = {\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * props: {\n * terminal: 'end',\n * normalizedAnchor: { x: 0.5, y: 0.5 },\n * isExact: false,\n * isPrecise: true\n * }\n * }\n *\n * editor.createBindings([newBinding])\n * ```\n *\n * @public\n */\nexport type TLBindingCreate<T extends TLBinding = TLBinding> = Expand<{\n\tid?: TLBindingId\n\ttype: T['type']\n\ttypeName?: T['typeName']\n\tfromId: T['fromId']\n\ttoId: T['toId']\n\tprops?: Partial<T['props']>\n\tmeta?: Partial<T['meta']>\n}>\n\n/**\n * Branded string type for binding record identifiers.\n * Prevents mixing binding IDs with other types of record IDs at compile time.\n *\n * @example\n * ```ts\n * import { createBindingId } from '@tldraw/tlschema'\n *\n * // Create a new binding ID\n * const bindingId: TLBindingId = createBindingId()\n *\n * // Use in binding records\n * const binding: TLBinding = {\n * id: bindingId,\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * // ... other properties\n * }\n * ```\n *\n * @public\n */\nexport type TLBindingId = RecordId<TLUnknownBinding>\n\n/**\n * Migration version identifiers for the root binding record schema.\n * Currently empty as no migrations have been applied to the base binding structure.\n *\n * @example\n * ```ts\n * // Future migrations would be defined here\n * const rootBindingVersions = createMigrationIds('com.tldraw.binding', {\n * AddNewProperty: 1,\n * } as const)\n * ```\n *\n * @public\n */\nexport const rootBindingVersions = createMigrationIds('com.tldraw.binding', {} as const)\n\n/**\n * Migration sequence for the root binding record structure.\n * Currently empty as the binding schema has not required any migrations yet.\n *\n * @example\n * ```ts\n * // Migrations would be automatically applied when loading old documents\n * const migratedStore = migrator.migrateStoreSnapshot({\n * schema: oldSchema,\n * store: oldStoreSnapshot\n * })\n * ```\n *\n * @public\n */\nexport const rootBindingMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.binding',\n\trecordType: 'binding',\n\tsequence: [],\n})\n\n/**\n * Type guard to check if a record is a TLBinding.\n * Useful for filtering or type narrowing when working with mixed record types.\n *\n * @param record - The record to check\n * @returns True if the record is a binding, false otherwise\n *\n * @example\n * ```ts\n * // Filter bindings from mixed records\n * const allRecords = store.allRecords()\n * const bindings = allRecords.filter(isBinding)\n *\n * // Type guard usage\n * function processRecord(record: UnknownRecord) {\n * if (isBinding(record)) {\n * // record is now typed as TLBinding\n * console.log(`Binding from ${record.fromId} to ${record.toId}`)\n * }\n * }\n * ```\n *\n * @public\n */\nexport function isBinding(record?: UnknownRecord): record is TLBinding {\n\tif (!record) return false\n\treturn record.typeName === 'binding'\n}\n\n/**\n * Type guard to check if a string is a valid TLBindingId.\n * Validates that the ID follows the correct format for binding identifiers.\n *\n * @param id - The string to check\n * @returns True if the string is a valid binding ID, false otherwise\n *\n * @example\n * ```ts\n * // Validate binding IDs\n * const maybeBindingId = 'binding:abc123'\n * if (isBindingId(maybeBindingId)) {\n * // maybeBindingId is now typed as TLBindingId\n * const binding = store.get(maybeBindingId)\n * }\n *\n * // Filter binding IDs from mixed ID array\n * const mixedIds = ['shape:1', 'binding:2', 'page:3']\n * const bindingIds = mixedIds.filter(isBindingId)\n * ```\n *\n * @public\n */\nexport function isBindingId(id?: string): id is TLBindingId {\n\tif (!id) return false\n\treturn id.startsWith('binding:')\n}\n\n/**\n * Creates a new TLBindingId with proper formatting.\n * Generates a unique ID if none is provided, or formats a provided ID correctly.\n *\n * @param id - Optional custom ID suffix. If not provided, a unique ID is generated\n * @returns A properly formatted binding ID\n *\n * @example\n * ```ts\n * // Create with auto-generated ID\n * const bindingId1 = createBindingId() // 'binding:abc123'\n *\n * // Create with custom ID\n * const bindingId2 = createBindingId('myCustomBinding') // 'binding:myCustomBinding'\n *\n * // Use in binding creation\n * const binding: TLBinding = {\n * id: createBindingId(),\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * // ... other properties\n * }\n * ```\n *\n * @public\n */\nexport function createBindingId(id?: string): TLBindingId {\n\treturn `binding:${id ?? uniqueId()}` as TLBindingId\n}\n\n/**\n * Creates a migration sequence for binding properties.\n * This is a pass-through function that validates and returns the provided migrations.\n *\n * @param migrations - The migration sequence for binding properties\n * @returns The validated migration sequence\n *\n * @example\n * ```ts\n * // Define migrations for custom binding properties\n * const myBindingMigrations = createBindingPropsMigrationSequence({\n * sequence: [\n * {\n * id: 'com.myapp.binding.custom/1.0.0',\n * up: (props) => ({ ...props, newProperty: 'default' }),\n * down: ({ newProperty, ...props }) => props\n * }\n * ]\n * })\n * ```\n *\n * @public\n */\nexport function createBindingPropsMigrationSequence(\n\tmigrations: TLPropsMigrations\n): TLPropsMigrations {\n\treturn migrations\n}\n\n/**\n * Creates properly formatted migration IDs for binding property migrations.\n * Follows the convention: 'com.tldraw.binding.\\{bindingType\\}/\\{version\\}'\n *\n * @param bindingType - The type of binding these migrations apply to\n * @param ids - Object mapping migration names to version numbers\n * @returns Object with formatted migration IDs\n *\n * @example\n * ```ts\n * // Create migration IDs for custom binding\n * const myBindingVersions = createBindingPropsMigrationIds('myCustomBinding', {\n * AddNewProperty: 1,\n * UpdateProperty: 2\n * })\n *\n * // Result:\n * // {\n * // AddNewProperty: 'com.tldraw.binding.myCustomBinding/1',\n * // UpdateProperty: 'com.tldraw.binding.myCustomBinding/2'\n * // }\n * ```\n *\n * @public\n */\nexport function createBindingPropsMigrationIds<S extends string, T extends Record<string, number>>(\n\tbindingType: S,\n\tids: T\n): { [k in keyof T]: `com.tldraw.binding.${S}/${T[k]}` } {\n\treturn mapObjectMapValues(ids, (_k, v) => `com.tldraw.binding.${bindingType}/${v}`) as any\n}\n\n/**\n * Creates a record type for TLBinding with validation based on the provided binding schemas.\n * This function is used internally to configure the binding record type in the schema.\n *\n * @param bindings - Record mapping binding type names to their schema information\n * @returns A configured record type for bindings with validation\n *\n * @example\n * ```ts\n * // Used internally when creating schemas\n * const bindingRecordType = createBindingRecordType({\n * arrow: {\n * props: arrowBindingProps,\n * meta: arrowBindingMeta\n * }\n * })\n * ```\n *\n * @internal\n */\nexport function createBindingRecordType(bindings: Record<string, SchemaPropsInfo>) {\n\treturn createRecordType<TLBinding>('binding', {\n\t\tscope: 'document',\n\t\tvalidator: T.model(\n\t\t\t'binding',\n\t\t\tT.union(\n\t\t\t\t'type',\n\t\t\t\tmapObjectMapValues(bindings, (type, { props, meta }) =>\n\t\t\t\t\tcreateBindingValidator(type, props, meta)\n\t\t\t\t)\n\t\t\t)\n\t\t),\n\t}).withDefaultProperties(() => ({\n\t\tmeta: {},\n\t}))\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAMO;AACP,mBAAqD;AACrD,sBAAkB;AAElB,2BAAsD;AA8K/C,MAAM,0BAAsB,iCAAmB,sBAAsB,CAAC,CAAU;AAiBhF,MAAM,4BAAwB,4CAA8B;AAAA,EAClE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU,CAAC;AACZ,CAAC;AA0BM,SAAS,UAAU,QAA6C;AACtE,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,aAAa;AAC5B;AAyBO,SAAS,YAAY,IAAgC;AAC3D,MAAI,CAAC,GAAI,QAAO;AAChB,SAAO,GAAG,WAAW,UAAU;AAChC;AA6BO,SAAS,gBAAgB,IAA0B;AACzD,SAAO,WAAW,UAAM,uBAAS,CAAC;AACnC;AAyBO,SAAS,oCACf,YACoB;AACpB,SAAO;AACR;AA2BO,SAAS,+BACf,aACA,KACwD;AACxD,aAAO,iCAAmB,KAAK,CAAC,IAAI,MAAM,sBAAsB,WAAW,IAAI,CAAC,EAAE;AACnF;AAsBO,SAAS,wBAAwB,UAA2C;AAClF,aAAO,+BAA4B,WAAW;AAAA,IAC7C,OAAO;AAAA,IACP,WAAW,kBAAE;AAAA,MACZ;AAAA,MACA,kBAAE;AAAA,QACD;AAAA,YACA;AAAA,UAAmB;AAAA,UAAU,CAAC,MAAM,EAAE,OAAO,KAAK,UACjD,6CAAuB,MAAM,OAAO,IAAI;AAAA,QACzC;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC,EAAE,sBAAsB,OAAO;AAAA,IAC/B,MAAM,CAAC;AAAA,EACR,EAAE;AACH;",
4
+ "sourcesContent": ["import {\n\tRecordId,\n\tUnknownRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n} from '@tldraw/store'\nimport { mapObjectMapValues, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { TLArrowBinding } from '../bindings/TLArrowBinding'\nimport { TLBaseBinding, createBindingValidator } from '../bindings/TLBaseBinding'\nimport { SchemaPropsInfo } from '../createTLSchema'\nimport { TLPropsMigrations } from '../recordsWithProps'\n\n/**\n * The default set of bindings that are available in the editor.\n * Currently includes only arrow bindings, but can be extended with custom bindings.\n *\n * @example\n * ```ts\n * // Arrow binding connects an arrow to shapes\n * const arrowBinding: TLDefaultBinding = {\n * id: 'binding:arrow1',\n * typeName: 'binding',\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * props: {\n * terminal: 'end',\n * normalizedAnchor: { x: 0.5, y: 0.5 },\n * isExact: false,\n * isPrecise: true\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLDefaultBinding = TLArrowBinding\n\n/**\n * A type for a binding that is available in the editor but whose type is\n * unknown\u2014either one of the editor's default bindings or else a custom binding.\n * Used internally for type-safe handling of bindings with unknown structure.\n *\n * @example\n * ```ts\n * // Function that works with any binding type\n * function processBinding(binding: TLUnknownBinding) {\n * console.log(`Processing ${binding.type} binding from ${binding.fromId} to ${binding.toId}`)\n * // Handle binding properties generically\n * }\n * ```\n *\n * @public\n */\nexport type TLUnknownBinding = TLBaseBinding<string, object>\n\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface TLGlobalBindingPropsMap {}\n\n/** @public */\n// prettier-ignore\nexport type TLIndexedBindings = {\n\t// We iterate over a union of augmented keys and default binding types.\n\t// This allows us to include (or conditionally exclude or override) the default bindings in one go.\n\t//\n\t// In the `as` clause we are filtering out disabled bindings.\n\t[K in keyof TLGlobalBindingPropsMap | TLDefaultBinding['type'] as K extends TLDefaultBinding['type']\n\t\t? K extends keyof TLGlobalBindingPropsMap\n\t\t\t? // if it extends a nullish value the user has disabled this binding type so we filter it out with never\n\t\t\t\tTLGlobalBindingPropsMap[K] extends null | undefined\n\t\t\t\t? never\n\t\t\t\t: K\n\t\t\t: K\n\t\t: K]: K extends TLDefaultBinding['type']\n\t\t\t? // if it's a default binding type we need to check if it's been overridden\n\t\t\t\tK extends keyof TLGlobalBindingPropsMap\n\t\t\t\t? // if it has been overriden then use the custom binding definition\n\t\t\t\t\tTLBaseBinding<K, TLGlobalBindingPropsMap[K]>\n\t\t\t\t: // if it has not been overriden then reuse existing type aliases for better type display\n\t\t\t\t\tExtract<TLDefaultBinding, { type: K }>\n\t\t\t: // use the custom binding definition\n\t\t\t\tTLBaseBinding<K, TLGlobalBindingPropsMap[K & keyof TLGlobalBindingPropsMap]>\n}\n\n/**\n * The set of all bindings that are available in the editor.\n * Bindings represent relationships between shapes, such as arrows connecting to other shapes.\n *\n * You can use this type without a type argument to work with any binding, or pass\n * a specific binding type string (e.g., `'arrow'`) to narrow down to that specific binding type.\n *\n * @example\n * ```ts\n * // Check binding type and handle accordingly\n * function handleBinding(binding: TLBinding) {\n * switch (binding.type) {\n * case 'arrow':\n * // Handle arrow binding\n * break\n * default:\n * // Handle unknown custom binding\n * break\n * }\n * }\n *\n * // Narrow to a specific binding type by passing the type as a generic argument\n * function getArrowSourceId(binding: TLBinding<'arrow'>) {\n * return binding.fromId // TypeScript knows this is a TLArrowBinding\n * }\n * ```\n *\n * @public\n */\nexport type TLBinding<K extends keyof TLIndexedBindings = keyof TLIndexedBindings> =\n\tTLIndexedBindings[K]\n\n/**\n * Type for updating existing bindings with partial properties.\n * Only the id and type are required, all other properties are optional.\n *\n * @example\n * ```ts\n * // Update arrow binding properties\n * const bindingUpdate: TLBindingUpdate<TLArrowBinding> = {\n * id: 'binding:arrow1',\n * type: 'arrow',\n * props: {\n * normalizedAnchor: { x: 0.7, y: 0.3 } // Only update anchor position\n * }\n * }\n *\n * editor.updateBindings([bindingUpdate])\n * ```\n *\n * @public\n */\nexport type TLBindingUpdate<T extends TLBinding = TLBinding> = T extends T\n\t? {\n\t\t\tid: TLBindingId\n\t\t\ttype: T['type']\n\t\t\ttypeName?: T['typeName']\n\t\t\tfromId?: T['fromId']\n\t\t\ttoId?: T['toId']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t}\n\t: never\n\n/**\n * Type for creating new bindings with required fromId and toId.\n * The id is optional and will be generated if not provided.\n *\n * @example\n * ```ts\n * // Create a new arrow binding\n * const newBinding: TLBindingCreate<TLArrowBinding> = {\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * props: {\n * terminal: 'end',\n * normalizedAnchor: { x: 0.5, y: 0.5 },\n * isExact: false,\n * isPrecise: true\n * }\n * }\n *\n * editor.createBindings([newBinding])\n * ```\n *\n * @public\n */\nexport type TLBindingCreate<T extends TLBinding = TLBinding> = T extends T\n\t? {\n\t\t\tid?: TLBindingId\n\t\t\ttype: T['type']\n\t\t\ttypeName?: T['typeName']\n\t\t\tfromId: T['fromId']\n\t\t\ttoId: T['toId']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t}\n\t: never\n\n/**\n * Branded string type for binding record identifiers.\n * Prevents mixing binding IDs with other types of record IDs at compile time.\n *\n * @example\n * ```ts\n * import { createBindingId } from '@tldraw/tlschema'\n *\n * // Create a new binding ID\n * const bindingId: TLBindingId = createBindingId()\n *\n * // Use in binding records\n * const binding: TLBinding = {\n * id: bindingId,\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * // ... other properties\n * }\n * ```\n *\n * @public\n */\nexport type TLBindingId = RecordId<TLBinding>\n\n/**\n * Migration version identifiers for the root binding record schema.\n * Currently empty as no migrations have been applied to the base binding structure.\n *\n * @example\n * ```ts\n * // Future migrations would be defined here\n * const rootBindingVersions = createMigrationIds('com.tldraw.binding', {\n * AddNewProperty: 1,\n * } as const)\n * ```\n *\n * @public\n */\nexport const rootBindingVersions = createMigrationIds('com.tldraw.binding', {} as const)\n\n/**\n * Migration sequence for the root binding record structure.\n * Currently empty as the binding schema has not required any migrations yet.\n *\n * @example\n * ```ts\n * // Migrations would be automatically applied when loading old documents\n * const migratedStore = migrator.migrateStoreSnapshot({\n * schema: oldSchema,\n * store: oldStoreSnapshot\n * })\n * ```\n *\n * @public\n */\nexport const rootBindingMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.binding',\n\trecordType: 'binding',\n\tsequence: [],\n})\n\n/**\n * Type guard to check if a record is a TLBinding.\n * Useful for filtering or type narrowing when working with mixed record types.\n *\n * @param record - The record to check\n * @returns True if the record is a binding, false otherwise\n *\n * @example\n * ```ts\n * // Filter bindings from mixed records\n * const allRecords = store.allRecords()\n * const bindings = allRecords.filter(isBinding)\n *\n * // Type guard usage\n * function processRecord(record: UnknownRecord) {\n * if (isBinding(record)) {\n * // record is now typed as TLBinding\n * console.log(`Binding from ${record.fromId} to ${record.toId}`)\n * }\n * }\n * ```\n *\n * @public\n */\nexport function isBinding(record?: UnknownRecord): record is TLBinding {\n\tif (!record) return false\n\treturn record.typeName === 'binding'\n}\n\n/**\n * Type guard to check if a string is a valid TLBindingId.\n * Validates that the ID follows the correct format for binding identifiers.\n *\n * @param id - The string to check\n * @returns True if the string is a valid binding ID, false otherwise\n *\n * @example\n * ```ts\n * // Validate binding IDs\n * const maybeBindingId = 'binding:abc123'\n * if (isBindingId(maybeBindingId)) {\n * // maybeBindingId is now typed as TLBindingId\n * const binding = store.get(maybeBindingId)\n * }\n *\n * // Filter binding IDs from mixed ID array\n * const mixedIds = ['shape:1', 'binding:2', 'page:3']\n * const bindingIds = mixedIds.filter(isBindingId)\n * ```\n *\n * @public\n */\nexport function isBindingId(id?: string): id is TLBindingId {\n\tif (!id) return false\n\treturn id.startsWith('binding:')\n}\n\n/**\n * Creates a new TLBindingId with proper formatting.\n * Generates a unique ID if none is provided, or formats a provided ID correctly.\n *\n * @param id - Optional custom ID suffix. If not provided, a unique ID is generated\n * @returns A properly formatted binding ID\n *\n * @example\n * ```ts\n * // Create with auto-generated ID\n * const bindingId1 = createBindingId() // 'binding:abc123'\n *\n * // Create with custom ID\n * const bindingId2 = createBindingId('myCustomBinding') // 'binding:myCustomBinding'\n *\n * // Use in binding creation\n * const binding: TLBinding = {\n * id: createBindingId(),\n * type: 'arrow',\n * fromId: 'shape:arrow1',\n * toId: 'shape:rectangle1',\n * // ... other properties\n * }\n * ```\n *\n * @public\n */\nexport function createBindingId(id?: string): TLBindingId {\n\treturn `binding:${id ?? uniqueId()}` as TLBindingId\n}\n\n/**\n * Creates a migration sequence for binding properties.\n * This is a pass-through function that validates and returns the provided migrations.\n *\n * @param migrations - The migration sequence for binding properties\n * @returns The validated migration sequence\n *\n * @example\n * ```ts\n * // Define migrations for custom binding properties\n * const myBindingMigrations = createBindingPropsMigrationSequence({\n * sequence: [\n * {\n * id: 'com.myapp.binding.custom/1.0.0',\n * up: (props) => ({ ...props, newProperty: 'default' }),\n * down: ({ newProperty, ...props }) => props\n * }\n * ]\n * })\n * ```\n *\n * @public\n */\nexport function createBindingPropsMigrationSequence(\n\tmigrations: TLPropsMigrations\n): TLPropsMigrations {\n\treturn migrations\n}\n\n/**\n * Creates properly formatted migration IDs for binding property migrations.\n * Follows the convention: 'com.tldraw.binding.\\{bindingType\\}/\\{version\\}'\n *\n * @param bindingType - The type of binding these migrations apply to\n * @param ids - Object mapping migration names to version numbers\n * @returns Object with formatted migration IDs\n *\n * @example\n * ```ts\n * // Create migration IDs for custom binding\n * const myBindingVersions = createBindingPropsMigrationIds('myCustomBinding', {\n * AddNewProperty: 1,\n * UpdateProperty: 2\n * })\n *\n * // Result:\n * // {\n * // AddNewProperty: 'com.tldraw.binding.myCustomBinding/1',\n * // UpdateProperty: 'com.tldraw.binding.myCustomBinding/2'\n * // }\n * ```\n *\n * @public\n */\nexport function createBindingPropsMigrationIds<S extends string, T extends Record<string, number>>(\n\tbindingType: S,\n\tids: T\n): { [k in keyof T]: `com.tldraw.binding.${S}/${T[k]}` } {\n\treturn mapObjectMapValues(ids, (_k, v) => `com.tldraw.binding.${bindingType}/${v}`) as any\n}\n\n/**\n * Creates a record type for TLBinding with validation based on the provided binding schemas.\n * This function is used internally to configure the binding record type in the schema.\n *\n * @param bindings - Record mapping binding type names to their schema information\n * @returns A configured record type for bindings with validation\n *\n * @example\n * ```ts\n * // Used internally when creating schemas\n * const bindingRecordType = createBindingRecordType({\n * arrow: {\n * props: arrowBindingProps,\n * meta: arrowBindingMeta\n * }\n * })\n * ```\n *\n * @internal\n */\nexport function createBindingRecordType(bindings: Record<string, SchemaPropsInfo>) {\n\treturn createRecordType('binding', {\n\t\tscope: 'document',\n\t\tvalidator: T.model(\n\t\t\t'binding',\n\t\t\tT.union(\n\t\t\t\t'type',\n\t\t\t\tmapObjectMapValues(bindings, (type, { props, meta }) =>\n\t\t\t\t\tcreateBindingValidator(type, props, meta)\n\t\t\t\t)\n\t\t\t)\n\t\t),\n\t}).withDefaultProperties(() => ({\n\t\tmeta: {},\n\t}))\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAMO;AACP,mBAA6C;AAC7C,sBAAkB;AAElB,2BAAsD;AAwN/C,MAAM,0BAAsB,iCAAmB,sBAAsB,CAAC,CAAU;AAiBhF,MAAM,4BAAwB,4CAA8B;AAAA,EAClE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU,CAAC;AACZ,CAAC;AA0BM,SAAS,UAAU,QAA6C;AACtE,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,aAAa;AAC5B;AAyBO,SAAS,YAAY,IAAgC;AAC3D,MAAI,CAAC,GAAI,QAAO;AAChB,SAAO,GAAG,WAAW,UAAU;AAChC;AA6BO,SAAS,gBAAgB,IAA0B;AACzD,SAAO,WAAW,UAAM,uBAAS,CAAC;AACnC;AAyBO,SAAS,oCACf,YACoB;AACpB,SAAO;AACR;AA2BO,SAAS,+BACf,aACA,KACwD;AACxD,aAAO,iCAAmB,KAAK,CAAC,IAAI,MAAM,sBAAsB,WAAW,IAAI,CAAC,EAAE;AACnF;AAsBO,SAAS,wBAAwB,UAA2C;AAClF,aAAO,+BAAiB,WAAW;AAAA,IAClC,OAAO;AAAA,IACP,WAAW,kBAAE;AAAA,MACZ;AAAA,MACA,kBAAE;AAAA,QACD;AAAA,YACA;AAAA,UAAmB;AAAA,UAAU,CAAC,MAAM,EAAE,OAAO,KAAK,UACjD,6CAAuB,MAAM,OAAO,IAAI;AAAA,QACzC;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC,EAAE,sBAAsB,OAAO;AAAA,IAC/B,MAAM,CAAC;AAAA,EACR,EAAE;AACH;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/records/TLShape.ts"],
4
- "sourcesContent": ["import {\n\tRecordId,\n\tUnknownRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n} from '@tldraw/store'\nimport { mapObjectMapValues, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { SchemaPropsInfo } from '../createTLSchema'\nimport { TLPropsMigrations } from '../recordsWithProps'\nimport { TLArrowShape } from '../shapes/TLArrowShape'\nimport { TLBaseShape, createShapeValidator } from '../shapes/TLBaseShape'\nimport { TLBookmarkShape } from '../shapes/TLBookmarkShape'\nimport { TLDrawShape } from '../shapes/TLDrawShape'\nimport { TLEmbedShape } from '../shapes/TLEmbedShape'\nimport { TLFrameShape } from '../shapes/TLFrameShape'\nimport { TLGeoShape } from '../shapes/TLGeoShape'\nimport { TLGroupShape } from '../shapes/TLGroupShape'\nimport { TLHighlightShape } from '../shapes/TLHighlightShape'\nimport { TLImageShape } from '../shapes/TLImageShape'\nimport { TLLineShape } from '../shapes/TLLineShape'\nimport { TLNoteShape } from '../shapes/TLNoteShape'\nimport { TLTextShape } from '../shapes/TLTextShape'\nimport { TLVideoShape } from '../shapes/TLVideoShape'\nimport { StyleProp } from '../styles/StyleProp'\nimport { TLPageId } from './TLPage'\n\n/**\n * The default set of shapes that are available in the editor.\n *\n * This union type represents all the built-in shape types supported by tldraw,\n * including arrows, bookmarks, drawings, embeds, frames, geometry shapes,\n * groups, images, lines, notes, text, videos, and highlights.\n *\n * @example\n * ```ts\n * // Check if a shape is a default shape type\n * function isDefaultShape(shape: TLShape): shape is TLDefaultShape {\n * const defaultTypes = ['arrow', 'bookmark', 'draw', 'embed', 'frame', 'geo', 'group', 'image', 'line', 'note', 'text', 'video', 'highlight']\n * return defaultTypes.includes(shape.type)\n * }\n * ```\n *\n * @public\n */\nexport type TLDefaultShape =\n\t| TLArrowShape\n\t| TLBookmarkShape\n\t| TLDrawShape\n\t| TLEmbedShape\n\t| TLFrameShape\n\t| TLGeoShape\n\t| TLGroupShape\n\t| TLImageShape\n\t| TLLineShape\n\t| TLNoteShape\n\t| TLTextShape\n\t| TLVideoShape\n\t| TLHighlightShape\n\n/**\n * A type for a shape that is available in the editor but whose type is\n * unknown\u2014either one of the editor's default shapes or else a custom shape.\n *\n * This is useful when working with shapes generically without knowing their specific type.\n * The shape type is a string and props are a generic object.\n *\n * @example\n * ```ts\n * // Handle any shape regardless of its specific type\n * function processUnknownShape(shape: TLUnknownShape) {\n * console.log(`Processing shape of type: ${shape.type}`)\n * console.log(`Position: (${shape.x}, ${shape.y})`)\n * }\n * ```\n *\n * @public\n */\nexport type TLUnknownShape = TLBaseShape<string, object>\n\n/**\n * The set of all shapes that are available in the editor, including unknown shapes.\n *\n * This is the primary shape type used throughout tldraw. It includes both the\n * built-in default shapes and any custom shapes that might be added.\n *\n * @example\n * ```ts\n * // Work with any shape in the editor\n * function moveShape(shape: TLShape, deltaX: number, deltaY: number): TLShape {\n * return {\n * ...shape,\n * x: shape.x + deltaX,\n * y: shape.y + deltaY\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLShape = TLDefaultShape | TLUnknownShape\n\n/**\n * A partial version of a shape, useful for updates and patches.\n *\n * This type represents a shape where all properties except `id` and `type` are optional.\n * It's commonly used when updating existing shapes or creating shape patches.\n *\n * @example\n * ```ts\n * // Update a shape's position\n * const shapeUpdate: TLShapePartial = {\n * id: 'shape:123',\n * type: 'geo',\n * x: 100,\n * y: 200\n * }\n *\n * // Update shape properties\n * const propsUpdate: TLShapePartial<TLGeoShape> = {\n * id: 'shape:123',\n * type: 'geo',\n * props: {\n * w: 150,\n * h: 100\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLShapePartial<T extends TLShape = TLShape> = T extends T\n\t? {\n\t\t\tid: TLShapeId\n\t\t\ttype: T['type']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t} & Partial<Omit<T, 'type' | 'id' | 'props' | 'meta'>>\n\t: never\n\n/**\n * A unique identifier for a shape record.\n *\n * Shape IDs are branded strings that start with \"shape:\" followed by a unique identifier.\n * This type-safe approach prevents mixing up different types of record IDs.\n *\n * @example\n * ```ts\n * const shapeId: TLShapeId = createShapeId() // \"shape:abc123\"\n * const customId: TLShapeId = createShapeId('my-custom-id') // \"shape:my-custom-id\"\n * ```\n *\n * @public\n */\nexport type TLShapeId = RecordId<TLUnknownShape>\n\n/**\n * The ID of a shape's parent, which can be either a page or another shape.\n *\n * Shapes can be parented to pages (for top-level shapes) or to other shapes\n * (for shapes inside frames or groups).\n *\n * @example\n * ```ts\n * // Shape parented to a page\n * const pageParentId: TLParentId = 'page:main'\n *\n * // Shape parented to another shape (e.g., inside a frame)\n * const shapeParentId: TLParentId = 'shape:frame123'\n * ```\n *\n * @public\n */\nexport type TLParentId = TLPageId | TLShapeId\n\n/**\n * Migration version IDs for the root shape schema.\n *\n * These track the evolution of the base shape structure over time, ensuring\n * that shapes created in older versions can be migrated to newer formats.\n *\n * @example\n * ```ts\n * // Check if a migration needs to be applied\n * if (shapeVersion < rootShapeVersions.AddIsLocked) {\n * // Apply isLocked migration\n * }\n * ```\n *\n * @public\n */\nexport const rootShapeVersions = createMigrationIds('com.tldraw.shape', {\n\tAddIsLocked: 1,\n\tHoistOpacity: 2,\n\tAddMeta: 3,\n\tAddWhite: 4,\n} as const)\n\n/**\n * Migration sequence for the root shape record type.\n *\n * This sequence defines how shape records should be transformed when migrating\n * between different schema versions. Each migration handles a specific version\n * upgrade, ensuring data compatibility across tldraw versions.\n *\n * @public\n */\nexport const rootShapeMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.shape',\n\trecordType: 'shape',\n\tsequence: [\n\t\t{\n\t\t\tid: rootShapeVersions.AddIsLocked,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.isLocked = false\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tdelete record.isLocked\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: rootShapeVersions.HoistOpacity,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.opacity = Number(record.props.opacity ?? '1')\n\t\t\t\tdelete record.props.opacity\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tconst opacity = record.opacity\n\t\t\t\tdelete record.opacity\n\t\t\t\trecord.props.opacity =\n\t\t\t\t\topacity < 0.175\n\t\t\t\t\t\t? '0.1'\n\t\t\t\t\t\t: opacity < 0.375\n\t\t\t\t\t\t\t? '0.25'\n\t\t\t\t\t\t\t: opacity < 0.625\n\t\t\t\t\t\t\t\t? '0.5'\n\t\t\t\t\t\t\t\t: opacity < 0.875\n\t\t\t\t\t\t\t\t\t? '0.75'\n\t\t\t\t\t\t\t\t\t: '1'\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: rootShapeVersions.AddMeta,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.meta = {}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: rootShapeVersions.AddWhite,\n\t\t\tup: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tif (record.props.color === 'white') {\n\t\t\t\t\trecord.props.color = 'black'\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * Type guard to check if a record is a shape.\n *\n * @param record - The record to check\n * @returns True if the record is a shape, false otherwise\n *\n * @example\n * ```ts\n * const record = store.get('shape:abc123')\n * if (isShape(record)) {\n * console.log(`Shape type: ${record.type}`)\n * console.log(`Position: (${record.x}, ${record.y})`)\n * }\n * ```\n *\n * @public\n */\nexport function isShape(record?: UnknownRecord): record is TLShape {\n\tif (!record) return false\n\treturn record.typeName === 'shape'\n}\n\n/**\n * Type guard to check if a string is a valid shape ID.\n *\n * @param id - The string to check\n * @returns True if the string is a valid shape ID, false otherwise\n *\n * @example\n * ```ts\n * const id = 'shape:abc123'\n * if (isShapeId(id)) {\n * const shape = store.get(id) // TypeScript knows id is TLShapeId\n * }\n *\n * // Check user input\n * function selectShape(id: string) {\n * if (isShapeId(id)) {\n * editor.selectShape(id)\n * } else {\n * console.error('Invalid shape ID format')\n * }\n * }\n * ```\n *\n * @public\n */\nexport function isShapeId(id?: string): id is TLShapeId {\n\tif (!id) return false\n\treturn id.startsWith('shape:')\n}\n\n/**\n * Creates a new shape ID.\n *\n * @param id - Optional custom ID suffix. If not provided, a unique ID will be generated\n * @returns A new shape ID with the \"shape:\" prefix\n *\n * @example\n * ```ts\n * // Create a shape with auto-generated ID\n * const shapeId = createShapeId() // \"shape:abc123\"\n *\n * // Create a shape with custom ID\n * const customShapeId = createShapeId('my-rectangle') // \"shape:my-rectangle\"\n *\n * // Use in shape creation\n * const newShape: TLGeoShape = {\n * id: createShapeId(),\n * type: 'geo',\n * x: 100,\n * y: 200,\n * // ... other properties\n * }\n * ```\n *\n * @public\n */\nexport function createShapeId(id?: string): TLShapeId {\n\treturn `shape:${id ?? uniqueId()}` as TLShapeId\n}\n\n/**\n * Extracts style properties from a shape's props definition and maps them to their property keys.\n *\n * This function analyzes shape property validators to identify which ones are style properties\n * and creates a mapping from StyleProp instances to their corresponding property keys.\n * It also validates that each style property is only used once per shape.\n *\n * @param props - Record of property validators for a shape type\n * @returns Map from StyleProp instances to their property keys\n * @throws Error if a style property is used more than once in the same shape\n *\n * @example\n * ```ts\n * const geoShapeProps = {\n * color: DefaultColorStyle,\n * fill: DefaultFillStyle,\n * width: T.number,\n * height: T.number\n * }\n *\n * const styleMap = getShapePropKeysByStyle(geoShapeProps)\n * // styleMap.get(DefaultColorStyle) === 'color'\n * // styleMap.get(DefaultFillStyle) === 'fill'\n * ```\n *\n * @internal\n */\nexport function getShapePropKeysByStyle(props: Record<string, T.Validatable<any>>) {\n\tconst propKeysByStyle = new Map<StyleProp<unknown>, string>()\n\tfor (const [key, prop] of Object.entries(props)) {\n\t\tif (prop instanceof StyleProp) {\n\t\t\tif (propKeysByStyle.has(prop)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Duplicate style prop ${prop.id}. Each style prop can only be used once within a shape.`\n\t\t\t\t)\n\t\t\t}\n\t\t\tpropKeysByStyle.set(prop, key)\n\t\t}\n\t}\n\treturn propKeysByStyle\n}\n\n/**\n * Creates a migration sequence for shape properties.\n *\n * This is a pass-through function that maintains the same structure as the input.\n * It's used for consistency and to provide a clear API for defining shape property migrations.\n *\n * @param migrations - The migration sequence to create\n * @returns The same migration sequence (pass-through)\n *\n * @example\n * ```ts\n * const myShapeMigrations = createShapePropsMigrationSequence({\n * sequence: [\n * {\n * id: 'com.myapp.shape.custom/1.0.0',\n * up: (props) => ({ ...props, newProperty: 'default' }),\n * down: ({ newProperty, ...props }) => props\n * }\n * ]\n * })\n * ```\n *\n * @public\n */\nexport function createShapePropsMigrationSequence(\n\tmigrations: TLPropsMigrations\n): TLPropsMigrations {\n\treturn migrations\n}\n\n/**\n * Creates properly formatted migration IDs for shape properties.\n *\n * Generates standardized migration IDs following the convention:\n * `com.tldraw.shape.{shapeType}/{version}`\n *\n * @param shapeType - The type of shape these migrations apply to\n * @param ids - Record mapping migration names to version numbers\n * @returns Record with the same keys but formatted migration ID values\n *\n * @example\n * ```ts\n * const myShapeVersions = createShapePropsMigrationIds('custom', {\n * AddColor: 1,\n * AddSize: 2,\n * RefactorProps: 3\n * })\n * // Result: {\n * // AddColor: 'com.tldraw.shape.custom/1',\n * // AddSize: 'com.tldraw.shape.custom/2',\n * // RefactorProps: 'com.tldraw.shape.custom/3'\n * // }\n * ```\n *\n * @public\n */\nexport function createShapePropsMigrationIds<\n\tconst S extends string,\n\tconst T extends Record<string, number>,\n>(shapeType: S, ids: T): { [k in keyof T]: `com.tldraw.shape.${S}/${T[k]}` } {\n\treturn mapObjectMapValues(ids, (_k, v) => `com.tldraw.shape.${shapeType}/${v}`) as any\n}\n\n/**\n * Creates the record type definition for shapes.\n *\n * This function generates a complete record type for shapes that includes validation\n * for all registered shape types. It combines the base shape properties with\n * type-specific properties and creates a union validator that can handle any\n * registered shape type.\n *\n * @param shapes - Record of shape type names to their schema configuration\n * @returns A complete RecordType for shapes with proper validation and default properties\n *\n * @example\n * ```ts\n * const shapeRecordType = createShapeRecordType({\n * geo: { props: geoShapeProps, migrations: geoMigrations },\n * arrow: { props: arrowShapeProps, migrations: arrowMigrations }\n * })\n * ```\n *\n * @internal\n */\nexport function createShapeRecordType(shapes: Record<string, SchemaPropsInfo>) {\n\treturn createRecordType<TLShape>('shape', {\n\t\tscope: 'document',\n\t\tvalidator: T.model(\n\t\t\t'shape',\n\t\t\tT.union(\n\t\t\t\t'type',\n\t\t\t\tmapObjectMapValues(shapes, (type, { props, meta }) =>\n\t\t\t\t\tcreateShapeValidator(type, props, meta)\n\t\t\t\t)\n\t\t\t)\n\t\t),\n\t}).withDefaultProperties(() => ({\n\t\tx: 0,\n\t\ty: 0,\n\t\trotation: 0,\n\t\tisLocked: false,\n\t\topacity: 1,\n\t\tmeta: {},\n\t}))\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tRecordId,\n\tUnknownRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n} from '@tldraw/store'\nimport { mapObjectMapValues, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { SchemaPropsInfo } from '../createTLSchema'\nimport { TLPropsMigrations } from '../recordsWithProps'\nimport { TLArrowShape } from '../shapes/TLArrowShape'\nimport { TLBaseShape, createShapeValidator } from '../shapes/TLBaseShape'\nimport { TLBookmarkShape } from '../shapes/TLBookmarkShape'\nimport { TLDrawShape } from '../shapes/TLDrawShape'\nimport { TLEmbedShape } from '../shapes/TLEmbedShape'\nimport { TLFrameShape } from '../shapes/TLFrameShape'\nimport { TLGeoShape } from '../shapes/TLGeoShape'\nimport { TLGroupShape } from '../shapes/TLGroupShape'\nimport { TLHighlightShape } from '../shapes/TLHighlightShape'\nimport { TLImageShape } from '../shapes/TLImageShape'\nimport { TLLineShape } from '../shapes/TLLineShape'\nimport { TLNoteShape } from '../shapes/TLNoteShape'\nimport { TLTextShape } from '../shapes/TLTextShape'\nimport { TLVideoShape } from '../shapes/TLVideoShape'\nimport { StyleProp } from '../styles/StyleProp'\nimport { TLPageId } from './TLPage'\n\n/**\n * The default set of shapes that are available in the editor.\n *\n * This union type represents all the built-in shape types supported by tldraw,\n * including arrows, bookmarks, drawings, embeds, frames, geometry shapes,\n * groups, images, lines, notes, text, videos, and highlights.\n *\n * @example\n * ```ts\n * // Check if a shape is a default shape type\n * function isDefaultShape(shape: TLShape): shape is TLDefaultShape {\n * const defaultTypes = ['arrow', 'bookmark', 'draw', 'embed', 'frame', 'geo', 'group', 'image', 'line', 'note', 'text', 'video', 'highlight']\n * return defaultTypes.includes(shape.type)\n * }\n * ```\n *\n * @public\n */\nexport type TLDefaultShape =\n\t| TLArrowShape\n\t| TLBookmarkShape\n\t| TLDrawShape\n\t| TLEmbedShape\n\t| TLFrameShape\n\t| TLGeoShape\n\t| TLGroupShape\n\t| TLImageShape\n\t| TLLineShape\n\t| TLNoteShape\n\t| TLTextShape\n\t| TLVideoShape\n\t| TLHighlightShape\n\n/**\n * A type for a shape that is available in the editor but whose type is\n * unknown\u2014either one of the editor's default shapes or else a custom shape.\n *\n * This is useful when working with shapes generically without knowing their specific type.\n * The shape type is a string and props are a generic object.\n *\n * @example\n * ```ts\n * // Handle any shape regardless of its specific type\n * function processUnknownShape(shape: TLUnknownShape) {\n * console.log(`Processing shape of type: ${shape.type}`)\n * console.log(`Position: (${shape.x}, ${shape.y})`)\n * }\n * ```\n *\n * @public\n */\nexport type TLUnknownShape = TLBaseShape<string, object>\n\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface TLGlobalShapePropsMap {}\n\n/** @public */\n// prettier-ignore\nexport type TLIndexedShapes = {\n\t// We iterate over a union of augmented keys and default shape types.\n\t// This allows us to include (or conditionally exclude or override) the default shapes in one go.\n\t//\n\t// In the `as` clause we are filtering out disabled shapes.\n\t[K in keyof TLGlobalShapePropsMap | TLDefaultShape['type'] as K extends TLDefaultShape['type']\n\t\t? // core shapes are always available and cannot be overridden so we just include them\n\t\t\tK extends 'group'\n\t\t\t? K\n\t\t\t: K extends keyof TLGlobalShapePropsMap\n\t\t\t\t? // if it extends a nullish value the user has disabled this shape type so we filter it out with never\n\t\t\t\t\tTLGlobalShapePropsMap[K] extends null | undefined\n\t\t\t\t\t? never\n\t\t\t\t\t: K\n\t\t\t\t: K\n\t\t: K]: K extends 'group'\n\t\t? // core shapes are always available and cannot be overridden so we just include them\n\t\t\tExtract<TLDefaultShape, { type: K }>\n\t\t: K extends TLDefaultShape['type']\n\t\t\t? // if it's a default shape type we need to check if it's been overridden\n\t\t\t\tK extends keyof TLGlobalShapePropsMap\n\t\t\t\t? // if it has been overriden then use the custom shape definition\n\t\t\t\t\tTLBaseShape<K, TLGlobalShapePropsMap[K]>\n\t\t\t\t: // if it has not been overriden then reuse existing type aliases for better type display\n\t\t\t\t\tExtract<TLDefaultShape, { type: K }>\n\t\t\t: // use the custom shape definition\n\t\t\t\tTLBaseShape<K, TLGlobalShapePropsMap[K & keyof TLGlobalShapePropsMap]>\n}\n\n/**\n * The set of all shapes that are available in the editor.\n *\n * This is the primary shape type used throughout tldraw. It includes both the\n * built-in default shapes and any custom shapes that might be added.\n *\n * You can use this type without a type argument to work with any shape, or pass\n * a specific shape type string (e.g., `'geo'`, `'arrow'`, `'text'`) to narrow\n * down to that specific shape type.\n *\n * @example\n * ```ts\n * // Work with any shape in the editor\n * function moveShape(shape: TLShape, deltaX: number, deltaY: number): TLShape {\n * return {\n * ...shape,\n * x: shape.x + deltaX,\n * y: shape.y + deltaY\n * }\n * }\n *\n * // Narrow to a specific shape type by passing the type as a generic argument\n * function getArrowLabel(shape: TLShape<'arrow'>): string {\n * return shape.props.text // TypeScript knows this is a TLArrowShape\n * }\n * ```\n *\n * @public\n */\nexport type TLShape<K extends keyof TLIndexedShapes = keyof TLIndexedShapes> = TLIndexedShapes[K]\n\n/**\n * A partial version of a shape, useful for updates and patches.\n *\n * This type represents a shape where all properties except `id` and `type` are optional.\n * It's commonly used when updating existing shapes or creating shape patches.\n *\n * @example\n * ```ts\n * // Update a shape's position\n * const shapeUpdate: TLShapePartial = {\n * id: 'shape:123',\n * type: 'geo',\n * x: 100,\n * y: 200\n * }\n *\n * // Update shape properties\n * const propsUpdate: TLShapePartial<TLGeoShape> = {\n * id: 'shape:123',\n * type: 'geo',\n * props: {\n * w: 150,\n * h: 100\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLShapePartial<T extends TLShape = TLShape> = T extends T\n\t? {\n\t\t\tid: TLShapeId\n\t\t\ttype: T['type']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t} & Partial<Omit<T, 'type' | 'id' | 'props' | 'meta'>>\n\t: never\n\n/**\n * A partial version of a shape, useful for creating shapes.\n *\n * This type represents a shape where all properties except `type` are optional.\n * It's commonly used when creating shapes.\n *\n * @example\n * ```ts\n * // Create a shape\n * const shapeCreate: TLCreateShapePartial = {\n * type: 'geo',\n * x: 100,\n * y: 200\n * }\n *\n * // Create shape properties\n * const propsCreate: TLCreateShapePartial<TLGeoShape> = {\n * type: 'geo',\n * props: {\n * w: 150,\n * h: 100\n * }\n * }\n * ```\n *\n * @public\n */\nexport type TLCreateShapePartial<T extends TLShape = TLShape> = T extends T\n\t? {\n\t\t\ttype: T['type']\n\t\t\tprops?: Partial<T['props']>\n\t\t\tmeta?: Partial<T['meta']>\n\t\t} & Partial<Omit<T, 'type' | 'props' | 'meta'>>\n\t: never\n\n/**\n * Extract a shape type by its props.\n *\n * This utility type takes a props object type and returns the corresponding shape type\n * from the TLShape union whose props match the given type.\n *\n * @example\n * ```ts\n * type MyShape = ExtractShapeByProps<{ w: number; h: number }>\n * // MyShape is now the type of shape(s) that have props with w and h as numbers\n * ```\n *\n * @public\n */\nexport type ExtractShapeByProps<P> = Extract<TLShape, { props: P }>\n\n/**\n * A unique identifier for a shape record.\n *\n * Shape IDs are branded strings that start with \"shape:\" followed by a unique identifier.\n * This type-safe approach prevents mixing up different types of record IDs.\n *\n * @example\n * ```ts\n * const shapeId: TLShapeId = createShapeId() // \"shape:abc123\"\n * const customId: TLShapeId = createShapeId('my-custom-id') // \"shape:my-custom-id\"\n * ```\n *\n * @public\n */\nexport type TLShapeId = RecordId<TLShape>\n\n/**\n * The ID of a shape's parent, which can be either a page or another shape.\n *\n * Shapes can be parented to pages (for top-level shapes) or to other shapes\n * (for shapes inside frames or groups).\n *\n * @example\n * ```ts\n * // Shape parented to a page\n * const pageParentId: TLParentId = 'page:main'\n *\n * // Shape parented to another shape (e.g., inside a frame)\n * const shapeParentId: TLParentId = 'shape:frame123'\n * ```\n *\n * @public\n */\nexport type TLParentId = TLPageId | TLShapeId\n\n/**\n * Migration version IDs for the root shape schema.\n *\n * These track the evolution of the base shape structure over time, ensuring\n * that shapes created in older versions can be migrated to newer formats.\n *\n * @example\n * ```ts\n * // Check if a migration needs to be applied\n * if (shapeVersion < rootShapeVersions.AddIsLocked) {\n * // Apply isLocked migration\n * }\n * ```\n *\n * @public\n */\nexport const rootShapeVersions = createMigrationIds('com.tldraw.shape', {\n\tAddIsLocked: 1,\n\tHoistOpacity: 2,\n\tAddMeta: 3,\n\tAddWhite: 4,\n})\n\n/**\n * Migration sequence for the root shape record type.\n *\n * This sequence defines how shape records should be transformed when migrating\n * between different schema versions. Each migration handles a specific version\n * upgrade, ensuring data compatibility across tldraw versions.\n *\n * @public\n */\nexport const rootShapeMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.shape',\n\trecordType: 'shape',\n\tsequence: [\n\t\t{\n\t\t\tid: rootShapeVersions.AddIsLocked,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.isLocked = false\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tdelete record.isLocked\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: rootShapeVersions.HoistOpacity,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.opacity = Number(record.props.opacity ?? '1')\n\t\t\t\tdelete record.props.opacity\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tconst opacity = record.opacity\n\t\t\t\tdelete record.opacity\n\t\t\t\trecord.props.opacity =\n\t\t\t\t\topacity < 0.175\n\t\t\t\t\t\t? '0.1'\n\t\t\t\t\t\t: opacity < 0.375\n\t\t\t\t\t\t\t? '0.25'\n\t\t\t\t\t\t\t: opacity < 0.625\n\t\t\t\t\t\t\t\t? '0.5'\n\t\t\t\t\t\t\t\t: opacity < 0.875\n\t\t\t\t\t\t\t\t\t? '0.75'\n\t\t\t\t\t\t\t\t\t: '1'\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: rootShapeVersions.AddMeta,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.meta = {}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: rootShapeVersions.AddWhite,\n\t\t\tup: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tif (record.props.color === 'white') {\n\t\t\t\t\trecord.props.color = 'black'\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * Type guard to check if a record is a shape.\n *\n * @param record - The record to check\n * @returns True if the record is a shape, false otherwise\n *\n * @example\n * ```ts\n * const record = store.get('shape:abc123')\n * if (isShape(record)) {\n * console.log(`Shape type: ${record.type}`)\n * console.log(`Position: (${record.x}, ${record.y})`)\n * }\n * ```\n *\n * @public\n */\nexport function isShape(record?: UnknownRecord): record is TLShape {\n\tif (!record) return false\n\treturn record.typeName === 'shape'\n}\n\n/**\n * Type guard to check if a string is a valid shape ID.\n *\n * @param id - The string to check\n * @returns True if the string is a valid shape ID, false otherwise\n *\n * @example\n * ```ts\n * const id = 'shape:abc123'\n * if (isShapeId(id)) {\n * const shape = store.get(id) // TypeScript knows id is TLShapeId\n * }\n *\n * // Check user input\n * function selectShape(id: string) {\n * if (isShapeId(id)) {\n * editor.selectShape(id)\n * } else {\n * console.error('Invalid shape ID format')\n * }\n * }\n * ```\n *\n * @public\n */\nexport function isShapeId(id?: string): id is TLShapeId {\n\tif (!id) return false\n\treturn id.startsWith('shape:')\n}\n\n/**\n * Creates a new shape ID.\n *\n * @param id - Optional custom ID suffix. If not provided, a unique ID will be generated\n * @returns A new shape ID with the \"shape:\" prefix\n *\n * @example\n * ```ts\n * // Create a shape with auto-generated ID\n * const shapeId = createShapeId() // \"shape:abc123\"\n *\n * // Create a shape with custom ID\n * const customShapeId = createShapeId('my-rectangle') // \"shape:my-rectangle\"\n *\n * // Use in shape creation\n * const newShape: TLGeoShape = {\n * id: createShapeId(),\n * type: 'geo',\n * x: 100,\n * y: 200,\n * // ... other properties\n * }\n * ```\n *\n * @public\n */\nexport function createShapeId(id?: string): TLShapeId {\n\treturn `shape:${id ?? uniqueId()}` as TLShapeId\n}\n\n/**\n * Extracts style properties from a shape's props definition and maps them to their property keys.\n *\n * This function analyzes shape property validators to identify which ones are style properties\n * and creates a mapping from StyleProp instances to their corresponding property keys.\n * It also validates that each style property is only used once per shape.\n *\n * @param props - Record of property validators for a shape type\n * @returns Map from StyleProp instances to their property keys\n * @throws Error if a style property is used more than once in the same shape\n *\n * @example\n * ```ts\n * const geoShapeProps = {\n * color: DefaultColorStyle,\n * fill: DefaultFillStyle,\n * width: T.number,\n * height: T.number\n * }\n *\n * const styleMap = getShapePropKeysByStyle(geoShapeProps)\n * // styleMap.get(DefaultColorStyle) === 'color'\n * // styleMap.get(DefaultFillStyle) === 'fill'\n * ```\n *\n * @internal\n */\nexport function getShapePropKeysByStyle(props: Record<string, T.Validatable<any>>) {\n\tconst propKeysByStyle = new Map<StyleProp<unknown>, string>()\n\tfor (const [key, prop] of Object.entries(props)) {\n\t\tif (prop instanceof StyleProp) {\n\t\t\tif (propKeysByStyle.has(prop)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Duplicate style prop ${prop.id}. Each style prop can only be used once within a shape.`\n\t\t\t\t)\n\t\t\t}\n\t\t\tpropKeysByStyle.set(prop, key)\n\t\t}\n\t}\n\treturn propKeysByStyle\n}\n\n/**\n * Creates a migration sequence for shape properties.\n *\n * This is a pass-through function that maintains the same structure as the input.\n * It's used for consistency and to provide a clear API for defining shape property migrations.\n *\n * @param migrations - The migration sequence to create\n * @returns The same migration sequence (pass-through)\n *\n * @example\n * ```ts\n * const myShapeMigrations = createShapePropsMigrationSequence({\n * sequence: [\n * {\n * id: 'com.myapp.shape.custom/1.0.0',\n * up: (props) => ({ ...props, newProperty: 'default' }),\n * down: ({ newProperty, ...props }) => props\n * }\n * ]\n * })\n * ```\n *\n * @public\n */\nexport function createShapePropsMigrationSequence(\n\tmigrations: TLPropsMigrations\n): TLPropsMigrations {\n\treturn migrations\n}\n\n/**\n * Creates properly formatted migration IDs for shape properties.\n *\n * Generates standardized migration IDs following the convention:\n * `com.tldraw.shape.{shapeType}/{version}`\n *\n * @param shapeType - The type of shape these migrations apply to\n * @param ids - Record mapping migration names to version numbers\n * @returns Record with the same keys but formatted migration ID values\n *\n * @example\n * ```ts\n * const myShapeVersions = createShapePropsMigrationIds('custom', {\n * AddColor: 1,\n * AddSize: 2,\n * RefactorProps: 3\n * })\n * // Result: {\n * // AddColor: 'com.tldraw.shape.custom/1',\n * // AddSize: 'com.tldraw.shape.custom/2',\n * // RefactorProps: 'com.tldraw.shape.custom/3'\n * // }\n * ```\n *\n * @public\n */\nexport function createShapePropsMigrationIds<\n\tconst S extends string,\n\tconst T extends Record<string, number>,\n>(shapeType: S, ids: T): { [k in keyof T]: `com.tldraw.shape.${S}/${T[k]}` } {\n\treturn mapObjectMapValues(ids, (_k, v) => `com.tldraw.shape.${shapeType}/${v}`) as any\n}\n\n/**\n * Creates the record type definition for shapes.\n *\n * This function generates a complete record type for shapes that includes validation\n * for all registered shape types. It combines the base shape properties with\n * type-specific properties and creates a union validator that can handle any\n * registered shape type.\n *\n * @param shapes - Record of shape type names to their schema configuration\n * @returns A complete RecordType for shapes with proper validation and default properties\n *\n * @example\n * ```ts\n * const shapeRecordType = createShapeRecordType({\n * geo: { props: geoShapeProps, migrations: geoMigrations },\n * arrow: { props: arrowShapeProps, migrations: arrowMigrations }\n * })\n * ```\n *\n * @internal\n */\nexport function createShapeRecordType(shapes: Record<string, SchemaPropsInfo>) {\n\treturn createRecordType('shape', {\n\t\tscope: 'document',\n\t\tvalidator: T.model(\n\t\t\t'shape',\n\t\t\tT.union(\n\t\t\t\t'type',\n\t\t\t\tmapObjectMapValues(shapes, (type, { props, meta }) =>\n\t\t\t\t\tcreateShapeValidator(type, props, meta)\n\t\t\t\t)\n\t\t\t)\n\t\t),\n\t}).withDefaultProperties(() => ({\n\t\tx: 0,\n\t\ty: 0,\n\t\trotation: 0,\n\t\tisLocked: false,\n\t\topacity: 1,\n\t\tmeta: {},\n\t}))\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/shapes/ShapeWithCrop.ts"],
4
- "sourcesContent": ["import { VecModel } from '../misc/geometry-types'\nimport { TLBaseShape } from './TLBaseShape'\n\n/**\n * Defines cropping parameters for shapes that support cropping.\n *\n * Specifies the visible area of an asset (like an image or video) within a shape.\n * The crop is defined by top-left and bottom-right coordinates in normalized space (0-1),\n * where (0,0) is the top-left of the original asset and (1,1) is the bottom-right.\n *\n * @example\n * ```ts\n * // Crop the center 50% of an image\n * const centerCrop: TLShapeCrop = {\n * topLeft: { x: 0.25, y: 0.25 },\n * bottomRight: { x: 0.75, y: 0.75 }\n * }\n *\n * // Crop for a circular image shape\n * const circleCrop: TLShapeCrop = {\n * topLeft: { x: 0, y: 0 },\n * bottomRight: { x: 1, y: 1 },\n * isCircle: true\n * }\n * ```\n *\n * @public\n */\nexport interface TLShapeCrop {\n\ttopLeft: VecModel\n\tbottomRight: VecModel\n\tisCircle?: boolean\n}\n\n/**\n * A shape type that supports cropping functionality.\n *\n * This type represents any shape that can display cropped content, typically media shapes\n * like images and videos. The shape has width, height, and optional crop parameters.\n * When crop is null, the entire asset is displayed.\n *\n * @example\n * ```ts\n * // An image shape with cropping\n * const croppedImageShape: ShapeWithCrop = {\n * id: 'shape:image1',\n * type: 'image',\n * x: 100,\n * y: 200,\n * // ... other base shape properties\n * props: {\n * w: 300,\n * h: 200,\n * crop: {\n * topLeft: { x: 0.1, y: 0.1 },\n * bottomRight: { x: 0.9, y: 0.9 }\n * }\n * }\n * }\n *\n * // A shape without cropping (shows full asset)\n * const fullImageShape: ShapeWithCrop = {\n * // ... shape properties\n * props: {\n * w: 400,\n * h: 300,\n * crop: null // Shows entire asset\n * }\n * }\n * ```\n *\n * @public\n */\nexport type ShapeWithCrop = TLBaseShape<string, { w: number; h: number; crop: TLShapeCrop | null }>\n"],
4
+ "sourcesContent": ["import { VecModel } from '../misc/geometry-types'\nimport { ExtractShapeByProps } from '../records/TLShape'\n\n/**\n * Defines cropping parameters for shapes that support cropping.\n *\n * Specifies the visible area of an asset (like an image or video) within a shape.\n * The crop is defined by top-left and bottom-right coordinates in normalized space (0-1),\n * where (0,0) is the top-left of the original asset and (1,1) is the bottom-right.\n *\n * @example\n * ```ts\n * // Crop the center 50% of an image\n * const centerCrop: TLShapeCrop = {\n * topLeft: { x: 0.25, y: 0.25 },\n * bottomRight: { x: 0.75, y: 0.75 }\n * }\n *\n * // Crop for a circular image shape\n * const circleCrop: TLShapeCrop = {\n * topLeft: { x: 0, y: 0 },\n * bottomRight: { x: 1, y: 1 },\n * isCircle: true\n * }\n * ```\n *\n * @public\n */\nexport interface TLShapeCrop {\n\ttopLeft: VecModel\n\tbottomRight: VecModel\n\tisCircle?: boolean\n}\n\n/**\n * A shape type that supports cropping functionality.\n *\n * This type represents any shape that can display cropped content, typically media shapes\n * like images and videos. The shape has width, height, and optional crop parameters.\n * When crop is null, the entire asset is displayed.\n *\n * @example\n * ```ts\n * // An image shape with cropping\n * const croppedImageShape: ShapeWithCrop = {\n * id: 'shape:image1',\n * type: 'image',\n * x: 100,\n * y: 200,\n * // ... other base shape properties\n * props: {\n * w: 300,\n * h: 200,\n * crop: {\n * topLeft: { x: 0.1, y: 0.1 },\n * bottomRight: { x: 0.9, y: 0.9 }\n * }\n * }\n * }\n *\n * // A shape without cropping (shows full asset)\n * const fullImageShape: ShapeWithCrop = {\n * // ... shape properties\n * props: {\n * w: 400,\n * h: 300,\n * crop: null // Shows entire asset\n * }\n * }\n * ```\n *\n * @public\n */\nexport type ShapeWithCrop = ExtractShapeByProps<{ w: number; h: number; crop: TLShapeCrop | null }>\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }