@tldraw/editor 3.8.0-canary.d9f1dbe89786 → 3.8.0-canary.da8c7dd47ae2

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 (93) hide show
  1. package/dist-cjs/index.d.ts +251 -59
  2. package/dist-cjs/index.js +14 -8
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +2 -5
  5. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  6. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
  7. package/dist-cjs/lib/config/createTLStore.js +4 -2
  8. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  9. package/dist-cjs/lib/editor/Editor.js +96 -21
  10. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  11. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
  12. package/dist-cjs/lib/editor/managers/TextManager.js +1 -0
  13. package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
  14. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  15. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js +66 -0
  16. package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js.map +7 -0
  17. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
  18. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  19. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  20. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  21. package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
  22. package/dist-cjs/lib/exports/exportToSvg.js.map +2 -2
  23. package/dist-cjs/lib/exports/getSvgAsImage.js +83 -0
  24. package/dist-cjs/lib/exports/getSvgAsImage.js.map +7 -0
  25. package/dist-cjs/lib/exports/getSvgJsx.js +16 -3
  26. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  27. package/dist-cjs/lib/hooks/useLocalStore.js +1 -1
  28. package/dist-cjs/lib/hooks/useLocalStore.js.map +2 -2
  29. package/dist-cjs/lib/options.js +2 -1
  30. package/dist-cjs/lib/options.js.map +2 -2
  31. package/dist-cjs/lib/utils/browserCanvasMaxSize.js +75 -0
  32. package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +7 -0
  33. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +3 -1
  34. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  35. package/dist-cjs/version.js +3 -3
  36. package/dist-cjs/version.js.map +1 -1
  37. package/dist-esm/index.d.mts +251 -59
  38. package/dist-esm/index.mjs +7 -1
  39. package/dist-esm/index.mjs.map +2 -2
  40. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +2 -5
  41. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  42. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  43. package/dist-esm/lib/config/createTLStore.mjs +4 -2
  44. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  45. package/dist-esm/lib/editor/Editor.mjs +96 -21
  46. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  47. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
  48. package/dist-esm/lib/editor/managers/TextManager.mjs +1 -0
  49. package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
  50. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  51. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs +46 -0
  52. package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs.map +7 -0
  53. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
  54. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
  55. package/dist-esm/lib/exports/exportToSvg.mjs.map +2 -2
  56. package/dist-esm/lib/exports/getSvgAsImage.mjs +63 -0
  57. package/dist-esm/lib/exports/getSvgAsImage.mjs.map +7 -0
  58. package/dist-esm/lib/exports/getSvgJsx.mjs +16 -3
  59. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  60. package/dist-esm/lib/hooks/useLocalStore.mjs +1 -1
  61. package/dist-esm/lib/hooks/useLocalStore.mjs.map +2 -2
  62. package/dist-esm/lib/options.mjs +2 -1
  63. package/dist-esm/lib/options.mjs.map +2 -2
  64. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +45 -0
  65. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +7 -0
  66. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +3 -1
  67. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  68. package/dist-esm/version.mjs +3 -3
  69. package/dist-esm/version.mjs.map +1 -1
  70. package/editor.css +2 -1
  71. package/package.json +22 -20
  72. package/src/index.ts +19 -1
  73. package/src/lib/components/default-components/DefaultCanvas.tsx +2 -5
  74. package/src/lib/config/TLSessionStateSnapshot.ts +3 -1
  75. package/src/lib/config/createTLStore.ts +4 -2
  76. package/src/lib/editor/Editor.ts +145 -55
  77. package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +4 -4
  78. package/src/lib/editor/managers/TextManager.ts +1 -0
  79. package/src/lib/editor/shapes/ShapeUtil.ts +30 -1
  80. package/src/lib/editor/shapes/shared/resizeScaled.ts +61 -0
  81. package/src/lib/editor/types/SvgExportContext.tsx +21 -0
  82. package/src/lib/editor/types/emit-types.ts +1 -0
  83. package/src/lib/editor/types/external-content.ts +90 -50
  84. package/src/lib/editor/types/misc-types.ts +55 -2
  85. package/src/lib/exports/StyleEmbedder.ts +1 -1
  86. package/src/lib/exports/exportToSvg.tsx +2 -2
  87. package/src/lib/exports/getSvgAsImage.ts +92 -0
  88. package/src/lib/exports/getSvgJsx.tsx +17 -2
  89. package/src/lib/hooks/useLocalStore.ts +1 -1
  90. package/src/lib/options.ts +6 -0
  91. package/src/lib/utils/browserCanvasMaxSize.ts +65 -0
  92. package/src/lib/utils/sync/TLLocalSyncClient.ts +3 -1
  93. package/src/version.ts +3 -3
@@ -2,57 +2,97 @@ import { TLAssetId } from '@tldraw/tlschema'
2
2
  import { VecLike } from '../../primitives/Vec'
3
3
  import { TLContent } from './clipboard-types'
4
4
 
5
+ /** @public */
6
+ export interface TLTldrawExternalContentSource {
7
+ type: 'tldraw'
8
+ data: TLContent
9
+ }
10
+
11
+ /** @public */
12
+ export interface TLExcalidrawExternalContentSource {
13
+ type: 'excalidraw'
14
+ data: any
15
+ }
16
+
17
+ /** @public */
18
+ export interface TLTextExternalContentSource {
19
+ type: 'text'
20
+ data: string
21
+ subtype: 'json' | 'html' | 'text' | 'url'
22
+ }
23
+
24
+ /** @public */
25
+ export interface TLErrorExternalContentSource {
26
+ type: 'error'
27
+ data: string | null
28
+ reason: string
29
+ }
30
+
5
31
  /** @public */
6
32
  export type TLExternalContentSource =
7
- | {
8
- type: 'tldraw'
9
- data: TLContent
10
- }
11
- | {
12
- type: 'excalidraw'
13
- data: any
14
- }
15
- | {
16
- type: 'text'
17
- data: string
18
- subtype: 'json' | 'html' | 'text' | 'url'
19
- }
20
- | {
21
- type: 'error'
22
- data: string | null
23
- reason: string
24
- }
25
-
26
- /** @public */
27
- export type TLExternalContent<EmbedDefinition> = {
33
+ | TLTldrawExternalContentSource
34
+ | TLExcalidrawExternalContentSource
35
+ | TLTextExternalContentSource
36
+ | TLErrorExternalContentSource
37
+
38
+ /** @public */
39
+ export interface TLBaseExternalContent {
28
40
  sources?: TLExternalContentSource[]
29
41
  point?: VecLike
30
- } & (
31
- | {
32
- type: 'text'
33
- text: string
34
- }
35
- | {
36
- type: 'files'
37
- files: File[]
38
- ignoreParent: boolean
39
- }
40
- | {
41
- type: 'url'
42
- url: string
43
- }
44
- | {
45
- type: 'svg-text'
46
- text: string
47
- }
48
- | {
49
- type: 'embed'
50
- url: string
51
- embed: EmbedDefinition
52
- }
53
- )
54
-
55
- /** @public */
56
- export type TLExternalAssetContent =
57
- | { type: 'file'; file: File; assetId?: TLAssetId }
58
- | { type: 'url'; url: string }
42
+ }
43
+
44
+ /** @public */
45
+ export interface TLTextExternalContent extends TLBaseExternalContent {
46
+ type: 'text'
47
+ text: string
48
+ }
49
+
50
+ /** @public */
51
+ export interface TLFilesExternalContent extends TLBaseExternalContent {
52
+ type: 'files'
53
+ files: File[]
54
+ ignoreParent: boolean
55
+ }
56
+
57
+ /** @public */
58
+ export interface TLUrlExternalContent extends TLBaseExternalContent {
59
+ type: 'url'
60
+ url: string
61
+ }
62
+
63
+ /** @public */
64
+ export interface TLSvgTextExternalContent extends TLBaseExternalContent {
65
+ type: 'svg-text'
66
+ text: string
67
+ }
68
+
69
+ /** @public */
70
+ export interface TLEmbedExternalContent<EmbedDefinition> extends TLBaseExternalContent {
71
+ type: 'embed'
72
+ url: string
73
+ embed: EmbedDefinition
74
+ }
75
+
76
+ /** @public */
77
+ export type TLExternalContent<EmbedDefinition> =
78
+ | TLTextExternalContent
79
+ | TLFilesExternalContent
80
+ | TLUrlExternalContent
81
+ | TLSvgTextExternalContent
82
+ | TLEmbedExternalContent<EmbedDefinition>
83
+
84
+ /** @public */
85
+ export interface TLFileExternalAsset {
86
+ type: 'file'
87
+ file: File
88
+ assetId?: TLAssetId
89
+ }
90
+
91
+ /** @public */
92
+ export interface TLUrlExternalAsset {
93
+ type: 'url'
94
+ url: string
95
+ }
96
+
97
+ /** @public */
98
+ export type TLExternalAsset = TLFileExternalAsset | TLUrlExternalAsset
@@ -8,17 +8,70 @@ export type RequiredKeys<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T,
8
8
  export type OptionalKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
9
9
 
10
10
  /** @public */
11
- export interface TLImageExportOptions {
11
+ export type TLExportType = 'svg' | 'png' | 'jpeg' | 'webp'
12
+
13
+ /** @public */
14
+ export interface TLSvgExportOptions {
15
+ /**
16
+ * The bounding box, in page coordinates, of the area being exported.
17
+ */
12
18
  bounds?: Box
19
+ /**
20
+ * The logical scale of the export. This scales the resulting size of the SVG being generated.
21
+ */
13
22
  scale?: number
14
- quality?: number
23
+ /**
24
+ * When exporting an SVG, the expected pixel ratio of the export will be passed in to
25
+ * {@link @tldraw/tlschema#TLAssetStore.resolve} as the `dpr` property, so that assets can be
26
+ * downscaled to the appropriate resolution.
27
+ *
28
+ * When exporting to a bitmap image format, the size of the resulting image will be multiplied
29
+ * by this number.
30
+ *
31
+ * For SVG exports, this defaults to undefined - which means we'll request original-quality
32
+ * assets. For bitmap exports, this defaults to 2.
33
+ */
15
34
  pixelRatio?: number
35
+
36
+ /**
37
+ * Should the background color be included in the export? If false, the generated image will be
38
+ * transparent (if exporting to a format that supports transparency).
39
+ */
16
40
  background?: boolean
41
+
42
+ /**
43
+ * How much padding to include around the bounds of exports? Defaults to 32px.
44
+ */
17
45
  padding?: number
46
+
47
+ /**
48
+ * Should the export be rendered in dark mode (true) or light mode (false)? Defaults to the
49
+ * current instance's dark mode setting.
50
+ */
18
51
  darkMode?: boolean
52
+
53
+ /**
54
+ * The
55
+ * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio | `preserveAspectRatio` }
56
+ * attribute of the SVG element.
57
+ */
19
58
  preserveAspectRatio?: React.SVGAttributes<SVGSVGElement>['preserveAspectRatio']
20
59
  }
21
60
 
61
+ /** @public */
62
+ export interface TLImageExportOptions extends TLSvgExportOptions {
63
+ /**
64
+ * If the export is being converted to a lossy bitmap format (e.g. jpeg), this is the quality of
65
+ * the export. This is a number between 0 and 1.
66
+ */
67
+ quality?: number
68
+
69
+ /**
70
+ * The format to export as. Defaults to 'png'.
71
+ */
72
+ format?: TLExportType
73
+ }
74
+
22
75
  /**
23
76
  * @public
24
77
  * @deprecated use {@link TLImageExportOptions} instead
@@ -54,7 +54,7 @@ export class StyleEmbedder {
54
54
  : NO_STYLES
55
55
 
56
56
  const parentStyles = shouldSkipInheritedParentStyles
57
- ? this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES
57
+ ? (this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES)
58
58
  : NO_STYLES
59
59
 
60
60
  const info: ElementStyleInfo = {
@@ -3,7 +3,7 @@ import { assert } from '@tldraw/utils'
3
3
  import { flushSync } from 'react-dom'
4
4
  import { createRoot } from 'react-dom/client'
5
5
  import { Editor } from '../editor/Editor'
6
- import { TLImageExportOptions } from '../editor/types/misc-types'
6
+ import { TLSvgExportOptions } from '../editor/types/misc-types'
7
7
  import { StyleEmbedder } from './StyleEmbedder'
8
8
  import { embedMedia } from './embedMedia'
9
9
  import { getSvgJsx } from './getSvgJsx'
@@ -13,7 +13,7 @@ let idCounter = 1
13
13
  export async function exportToSvg(
14
14
  editor: Editor,
15
15
  shapeIds: TLShapeId[],
16
- opts: TLImageExportOptions = {}
16
+ opts: TLSvgExportOptions = {}
17
17
  ) {
18
18
  // when rendering to SVG, we start by creating a JSX representation of the SVG that we can
19
19
  // render with react. Hopefully elements will have a `toSvg` method that renders them to SVG,
@@ -0,0 +1,92 @@
1
+ import { FileHelpers, Image, PngHelpers, sleep } from '@tldraw/utils'
2
+ import { tlenv } from '../globals/environment'
3
+ import { clampToBrowserMaxCanvasSize } from '../utils/browserCanvasMaxSize'
4
+ import { debugFlags } from '../utils/debug-flags'
5
+
6
+ /** @public */
7
+ export async function getSvgAsImage(
8
+ svgString: string,
9
+ options: {
10
+ type: 'png' | 'jpeg' | 'webp'
11
+ width: number
12
+ height: number
13
+ quality?: number
14
+ pixelRatio?: number
15
+ }
16
+ ) {
17
+ const { type, width, height, quality = 1, pixelRatio = 2 } = options
18
+
19
+ let [clampedWidth, clampedHeight] = await clampToBrowserMaxCanvasSize(
20
+ width * pixelRatio,
21
+ height * pixelRatio
22
+ )
23
+ clampedWidth = Math.floor(clampedWidth)
24
+ clampedHeight = Math.floor(clampedHeight)
25
+ const effectiveScale = clampedWidth / width
26
+
27
+ // usually we would use `URL.createObjectURL` here, but chrome has a bug where `blob:` URLs of
28
+ // SVGs that use <foreignObject> mark the canvas as tainted, where data: ones do not.
29
+ // https://issues.chromium.org/issues/41054640
30
+ const svgUrl = await FileHelpers.blobToDataUrl(new Blob([svgString], { type: 'image/svg+xml' }))
31
+
32
+ const canvas = await new Promise<HTMLCanvasElement | null>((resolve) => {
33
+ const image = Image()
34
+ image.crossOrigin = 'anonymous'
35
+
36
+ image.onload = async () => {
37
+ // safari will fire `onLoad` before the fonts in the SVG are
38
+ // actually loaded. just waiting around a while is brittle, but
39
+ // there doesn't seem to be any better solution for now :( see
40
+ // https://bugs.webkit.org/show_bug.cgi?id=219770
41
+ if (tlenv.isSafari) {
42
+ await sleep(250)
43
+ }
44
+
45
+ const canvas = document.createElement('canvas') as HTMLCanvasElement
46
+ const ctx = canvas.getContext('2d')!
47
+
48
+ canvas.width = clampedWidth
49
+ canvas.height = clampedHeight
50
+
51
+ ctx.imageSmoothingEnabled = true
52
+ ctx.imageSmoothingQuality = 'high'
53
+ ctx.drawImage(image, 0, 0, clampedWidth, clampedHeight)
54
+
55
+ URL.revokeObjectURL(svgUrl)
56
+
57
+ resolve(canvas)
58
+ }
59
+
60
+ image.onerror = () => {
61
+ resolve(null)
62
+ }
63
+
64
+ image.src = svgUrl
65
+ })
66
+
67
+ if (!canvas) return null
68
+
69
+ const blob = await new Promise<Blob | null>((resolve) =>
70
+ canvas.toBlob(
71
+ (blob) => {
72
+ if (!blob || debugFlags.throwToBlob.get()) {
73
+ resolve(null)
74
+ }
75
+ resolve(blob)
76
+ },
77
+ 'image/' + type,
78
+ quality
79
+ )
80
+ )
81
+
82
+ if (!blob) return null
83
+
84
+ if (type === 'png') {
85
+ const view = new DataView(await blob.arrayBuffer())
86
+ return PngHelpers.setPhysChunk(view, effectiveScale, {
87
+ type: 'image/' + type,
88
+ })
89
+ } else {
90
+ return blob
91
+ }
92
+ }
@@ -41,7 +41,7 @@ export function getSvgJsx(editor: Editor, ids: TLShapeId[], opts: TLImageExportO
41
41
  const {
42
42
  scale = 1,
43
43
  // should we include the background in the export? or is it transparent?
44
- background = false,
44
+ background = editor.getInstanceState().exportBackground,
45
45
  padding = editor.options.defaultSvgPadding,
46
46
  preserveAspectRatio,
47
47
  } = opts
@@ -102,6 +102,7 @@ export function getSvgJsx(editor: Editor, ids: TLShapeId[], opts: TLImageExportO
102
102
  editor={editor}
103
103
  preserveAspectRatio={preserveAspectRatio}
104
104
  scale={scale}
105
+ pixelRatio={opts.pixelRatio ?? null}
105
106
  bbox={bbox}
106
107
  background={background}
107
108
  singleFrameShapeId={singleFrameShapeId}
@@ -121,6 +122,7 @@ function SvgExport({
121
122
  editor,
122
123
  preserveAspectRatio,
123
124
  scale,
125
+ pixelRatio,
124
126
  bbox,
125
127
  background,
126
128
  singleFrameShapeId,
@@ -132,6 +134,7 @@ function SvgExport({
132
134
  editor: Editor
133
135
  preserveAspectRatio?: string
134
136
  scale: number
137
+ pixelRatio: number | null
135
138
  bbox: Box
136
139
  background: boolean
137
140
  singleFrameShapeId: TLShapeId | null
@@ -177,8 +180,20 @@ function SvgExport({
177
180
  isDarkMode,
178
181
  waitUntil,
179
182
  addExportDef,
183
+ scale,
184
+ pixelRatio,
185
+ async resolveAssetUrl(assetId, width) {
186
+ const asset = editor.getAsset(assetId)
187
+ if (!asset || (asset.type !== 'image' && asset.type !== 'video')) return null
188
+
189
+ return await editor.resolveAssetUrl(assetId, {
190
+ screenScale: scale * (width / asset.props.w),
191
+ shouldResolveToOriginal: pixelRatio === null,
192
+ dpr: pixelRatio ?? undefined,
193
+ })
194
+ },
180
195
  }),
181
- [isDarkMode, waitUntil, addExportDef]
196
+ [isDarkMode, waitUntil, addExportDef, scale, pixelRatio, editor]
182
197
  )
183
198
 
184
199
  const didRenderRef = useRef(false)
@@ -37,7 +37,7 @@ export function useLocalStore(
37
37
  const assets: TLAssetStore = {
38
38
  upload: async (asset, file) => {
39
39
  await client.db.storeAsset(asset.id, file)
40
- return asset.id
40
+ return { src: asset.id }
41
41
  },
42
42
  resolve: async (asset) => {
43
43
  if (!asset.props.src) return null
@@ -66,6 +66,11 @@ export interface TldrawOptions {
66
66
  * external context providers. By default, this is `React.Fragment`.
67
67
  */
68
68
  readonly exportProvider: ComponentType<{ children: React.ReactNode }>
69
+ /**
70
+ * How should the note shape resize? By default it does not resize (except automatically based on its text content),
71
+ * but you can set it to be user-resizable using scale.
72
+ */
73
+ readonly noteShapeResizeMode: 'none' | 'scale'
69
74
  }
70
75
 
71
76
  /** @public */
@@ -111,4 +116,5 @@ export const defaultTldrawOptions = {
111
116
  actionShortcutsLocation: 'swap',
112
117
  createTextOnCanvasDoubleClick: true,
113
118
  exportProvider: Fragment,
119
+ noteShapeResizeMode: 'none',
114
120
  } as const satisfies TldrawOptions
@@ -0,0 +1,65 @@
1
+ import canvasSize from 'canvas-size'
2
+
3
+ /** @internal */
4
+ export interface CanvasMaxSize {
5
+ maxWidth: number
6
+ maxHeight: number
7
+ maxArea: number
8
+ }
9
+
10
+ let maxSizePromise: Promise<CanvasMaxSize> | null = null
11
+
12
+ function getBrowserCanvasMaxSize() {
13
+ if (!maxSizePromise) {
14
+ maxSizePromise = calculateBrowserCanvasMaxSize()
15
+ }
16
+
17
+ return maxSizePromise
18
+ }
19
+
20
+ async function calculateBrowserCanvasMaxSize(): Promise<CanvasMaxSize> {
21
+ const maxWidth = await canvasSize.maxWidth({ usePromise: true })
22
+ const maxHeight = await canvasSize.maxHeight({ usePromise: true })
23
+ const maxArea = await canvasSize.maxArea({ usePromise: true })
24
+ return {
25
+ maxWidth: maxWidth.width,
26
+ maxHeight: maxHeight.height,
27
+ maxArea: maxArea.width * maxArea.height,
28
+ }
29
+ }
30
+
31
+ // https://github.com/jhildenbiddle/canvas-size?tab=readme-ov-file#test-results
32
+ const MAX_SAFE_CANVAS_DIMENSION = 8192
33
+ const MAX_SAFE_CANVAS_AREA = 4096 * 4096
34
+
35
+ /** @internal */
36
+ export async function clampToBrowserMaxCanvasSize(width: number, height: number) {
37
+ if (
38
+ width <= MAX_SAFE_CANVAS_DIMENSION &&
39
+ height <= MAX_SAFE_CANVAS_DIMENSION &&
40
+ width * height <= MAX_SAFE_CANVAS_AREA
41
+ ) {
42
+ return [width, height]
43
+ }
44
+
45
+ const { maxWidth, maxHeight, maxArea } = await getBrowserCanvasMaxSize()
46
+ const aspectRatio = width / height
47
+
48
+ if (width > maxWidth) {
49
+ width = maxWidth
50
+ height = width / aspectRatio
51
+ }
52
+
53
+ if (height > maxHeight) {
54
+ height = maxHeight
55
+ width = height * aspectRatio
56
+ }
57
+
58
+ if (width * height > maxArea) {
59
+ const ratio = Math.sqrt(maxArea / (width * height))
60
+ width *= ratio
61
+ height *= ratio
62
+ }
63
+
64
+ return [width, height]
65
+ }
@@ -196,7 +196,9 @@ export class TLLocalSyncClient {
196
196
  }
197
197
 
198
198
  if (sessionStateSnapshot) {
199
- loadSessionStateSnapshotIntoStore(this.store, sessionStateSnapshot)
199
+ loadSessionStateSnapshotIntoStore(this.store, sessionStateSnapshot, {
200
+ forceOverwrite: true,
201
+ })
200
202
  }
201
203
  }
202
204
 
package/src/version.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.8.0-canary.d9f1dbe89786'
4
+ export const version = '3.8.0-canary.da8c7dd47ae2'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-01-13T16:09:51.377Z',
8
- patch: '2025-01-13T16:09:51.377Z',
7
+ minor: '2025-01-31T11:32:41.948Z',
8
+ patch: '2025-01-31T11:32:41.948Z',
9
9
  }