@tldraw/tlschema 5.2.0-canary.43192064d0bf → 5.2.0-canary.463b08fade11
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.
- package/README.md +5 -1
- package/dist-cjs/index.d.ts +5 -5
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/records/TLInstance.js +3 -2
- package/dist-cjs/records/TLInstance.js.map +2 -2
- package/dist-cjs/records/TLPageState.js +5 -1
- package/dist-cjs/records/TLPageState.js.map +2 -2
- package/dist-cjs/records/TLPresence.js +3 -2
- package/dist-cjs/records/TLPresence.js.map +2 -2
- package/dist-esm/index.d.mts +5 -5
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/records/TLInstance.mjs +3 -2
- package/dist-esm/records/TLInstance.mjs.map +2 -2
- package/dist-esm/records/TLPageState.mjs +5 -1
- package/dist-esm/records/TLPageState.mjs.map +2 -2
- package/dist-esm/records/TLPresence.mjs +3 -2
- package/dist-esm/records/TLPresence.mjs.map +2 -2
- package/package.json +8 -5
- package/src/records/TLInstance.ts +5 -4
- package/src/records/TLPageState.ts +5 -1
- package/src/records/TLPresence.ts +5 -4
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@ Type definitions, schema migrations, and other type metadata for the tldraw edit
|
|
|
4
4
|
|
|
5
5
|
## Documentation
|
|
6
6
|
|
|
7
|
+
Documentation for the most recent release can be found on [tldraw.dev/docs](https://tldraw.dev/docs), including [reference docs](https://tldraw.dev/reference/editor/Editor). Our release notes can be found [here](https://tldraw.dev/releases).
|
|
8
|
+
|
|
9
|
+
For more agent-friendly docs, see our [LLMs.txt](https://tldraw.dev/llms.txt).
|
|
10
|
+
|
|
7
11
|
A `DOCS.md` file is included alongside this README in the published package, with detailed API documentation and usage examples.
|
|
8
12
|
|
|
9
13
|
## Records
|
|
@@ -84,7 +88,7 @@ You can find tldraw on npm [here](https://www.npmjs.com/package/@tldraw/tldraw?a
|
|
|
84
88
|
|
|
85
89
|
## Contribution
|
|
86
90
|
|
|
87
|
-
|
|
91
|
+
Found a bug? Please [submit an issue](https://github.com/tldraw/tldraw/issues/new).
|
|
88
92
|
|
|
89
93
|
## Community
|
|
90
94
|
|
package/dist-cjs/index.d.ts
CHANGED
|
@@ -1924,7 +1924,7 @@ export declare function getDefaultUserPresence(store: TLStore, user: TLUser): {
|
|
|
1924
1924
|
x: number;
|
|
1925
1925
|
y: number;
|
|
1926
1926
|
};
|
|
1927
|
-
followingUserId:
|
|
1927
|
+
followingUserId: TLUserId | null;
|
|
1928
1928
|
lastActivityTimestamp: number;
|
|
1929
1929
|
meta: {};
|
|
1930
1930
|
screenBounds: BoxModel;
|
|
@@ -5101,8 +5101,8 @@ export declare interface TLInstance extends BaseRecord<'instance', TLInstanceId>
|
|
|
5101
5101
|
currentPageId: TLPageId;
|
|
5102
5102
|
opacityForNextShape: TLOpacityType;
|
|
5103
5103
|
stylesForNextShape: Record<string, unknown>;
|
|
5104
|
-
followingUserId: null |
|
|
5105
|
-
highlightedUserIds:
|
|
5104
|
+
followingUserId: null | TLUserId;
|
|
5105
|
+
highlightedUserIds: TLUserId[];
|
|
5106
5106
|
brush: BoxModel | null;
|
|
5107
5107
|
cursor: TLCursor;
|
|
5108
5108
|
scribbles: TLScribble[];
|
|
@@ -5250,7 +5250,7 @@ export declare type TLInstancePageStateId = RecordId<TLInstancePageState>;
|
|
|
5250
5250
|
* @public
|
|
5251
5251
|
*/
|
|
5252
5252
|
export declare interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {
|
|
5253
|
-
userId:
|
|
5253
|
+
userId: TLUserId;
|
|
5254
5254
|
userName: string;
|
|
5255
5255
|
lastActivityTimestamp: null | number;
|
|
5256
5256
|
color: string;
|
|
@@ -5264,7 +5264,7 @@ export declare interface TLInstancePresence extends BaseRecord<'instance_presenc
|
|
|
5264
5264
|
brush: BoxModel | null;
|
|
5265
5265
|
scribbles: TLScribble[];
|
|
5266
5266
|
screenBounds: BoxModel | null;
|
|
5267
|
-
followingUserId: null |
|
|
5267
|
+
followingUserId: null | TLUserId;
|
|
5268
5268
|
cursor: {
|
|
5269
5269
|
rotation: number;
|
|
5270
5270
|
type: TLCursor['type'];
|
package/dist-cjs/index.js
CHANGED
|
@@ -205,7 +205,7 @@ var import_translations = require("./translations/translations");
|
|
|
205
205
|
var import_b64Vecs = require("./misc/b64Vecs");
|
|
206
206
|
(0, import_utils.registerTldrawLibraryVersion)(
|
|
207
207
|
"@tldraw/tlschema",
|
|
208
|
-
"5.2.0-canary.
|
|
208
|
+
"5.2.0-canary.463b08fade11",
|
|
209
209
|
"cjs"
|
|
210
210
|
);
|
|
211
211
|
//# sourceMappingURL=index.js.map
|
|
@@ -36,6 +36,7 @@ var import_TLCursor = require("../misc/TLCursor");
|
|
|
36
36
|
var import_TLOpacity = require("../misc/TLOpacity");
|
|
37
37
|
var import_TLScribble = require("../misc/TLScribble");
|
|
38
38
|
var import_TLPage = require("./TLPage");
|
|
39
|
+
var import_TLUser = require("./TLUser");
|
|
39
40
|
const shouldKeyBePreservedBetweenSessions = {
|
|
40
41
|
// This object defines keys that should be preserved across calls to loadSnapshot()
|
|
41
42
|
id: false,
|
|
@@ -118,7 +119,7 @@ function createInstanceRecordType(stylesById) {
|
|
|
118
119
|
typeName: import_validate.T.literal("instance"),
|
|
119
120
|
id: (0, import_id_validator.idValidator)("instance"),
|
|
120
121
|
currentPageId: import_TLPage.pageIdValidator,
|
|
121
|
-
followingUserId:
|
|
122
|
+
followingUserId: import_TLUser.userIdValidator.nullable(),
|
|
122
123
|
brush: import_geometry_types.boxModelValidator.nullable(),
|
|
123
124
|
opacityForNextShape: import_TLOpacity.opacityValidator,
|
|
124
125
|
stylesForNextShape: import_validate.T.object(stylesForNextShapeValidators),
|
|
@@ -135,7 +136,7 @@ function createInstanceRecordType(stylesById) {
|
|
|
135
136
|
isGridMode: import_validate.T.boolean,
|
|
136
137
|
chatMessage: import_validate.T.string,
|
|
137
138
|
isChatting: import_validate.T.boolean,
|
|
138
|
-
highlightedUserIds: import_validate.T.arrayOf(
|
|
139
|
+
highlightedUserIds: import_validate.T.arrayOf(import_TLUser.userIdValidator),
|
|
139
140
|
isFocused: import_validate.T.boolean,
|
|
140
141
|
devicePixelRatio: import_validate.T.number,
|
|
141
142
|
isCoarsePointer: import_validate.T.boolean,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/records/TLInstance.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { filterEntries, JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorValidator, TLCursor } from '../misc/TLCursor'\nimport { opacityValidator, TLOpacityType } from '../misc/TLOpacity'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { StyleProp } from '../styles/StyleProp'\nimport { pageIdValidator, TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * State that is particular to a single browser tab. The TLInstance record stores\n * all session-specific state including cursor position, selected tools, UI preferences,\n * and temporary interaction state.\n *\n * Each browser tab has exactly one TLInstance record that persists for the duration\n * of the session and tracks the user's current interaction state.\n *\n * @example\n * ```ts\n * const instance: TLInstance = {\n * id: 'instance:instance',\n * typeName: 'instance',\n * currentPageId: 'page:page1',\n * cursor: { type: 'default', rotation: 0 },\n * screenBounds: { x: 0, y: 0, w: 1920, h: 1080 },\n * isFocusMode: false,\n * isGridMode: true\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstance extends BaseRecord<'instance', TLInstanceId> {\n\tcurrentPageId: TLPageId\n\topacityForNextShape: TLOpacityType\n\tstylesForNextShape: Record<string, unknown>\n\tfollowingUserId: string | null\n\thighlightedUserIds: string[]\n\tbrush: BoxModel | null\n\tcursor: TLCursor\n\tscribbles: TLScribble[]\n\tisFocusMode: boolean\n\tisDebugMode: boolean\n\tisToolLocked: boolean\n\texportBackground: boolean\n\tscreenBounds: BoxModel\n\tinsets: boolean[]\n\tzoomBrush: BoxModel | null\n\tchatMessage: string\n\tisChatting: boolean\n\tisPenMode: boolean\n\tisGridMode: boolean\n\tisFocused: boolean\n\tdevicePixelRatio: number\n\t/**\n\t * This is whether the primary input mechanism includes a pointing device of limited accuracy,\n\t * such as a finger on a touchscreen.\n\t */\n\tisCoarsePointer: boolean\n\t/**\n\t * Will be null if the pointer doesn't support hovering (e.g. touch), but true or false\n\t * otherwise\n\t */\n\tisHoveringCanvas: boolean | null\n\topenMenus: string[]\n\tisChangingStyle: boolean\n\tisReadonly: boolean\n\tmeta: JsonObject\n\tduplicateProps: {\n\t\tshapeIds: TLShapeId[]\n\t\toffset: {\n\t\t\tx: number\n\t\t\ty: number\n\t\t}\n\t} | null\n\t/**\n\t * Whether the camera is currently moving or idle. Used to optimize rendering\n\t * and hit-testing during panning/zooming.\n\t */\n\tcameraState: 'idle' | 'moving'\n}\n\n/**\n * Configuration object defining which TLInstance properties should be preserved\n * when loading snapshots across browser sessions. Properties marked as `true`\n * represent user preferences that should persist, while `false` indicates\n * temporary state that should reset.\n *\n * @internal\n */\nexport const shouldKeyBePreservedBetweenSessions = {\n\t// This object defines keys that should be preserved across calls to loadSnapshot()\n\n\tid: false, // meta\n\ttypeName: false, // meta\n\n\tcurrentPageId: false, // does not preserve because who knows if the page still exists\n\topacityForNextShape: false, // does not preserve because it's a temporary state\n\tstylesForNextShape: false, // does not preserve because it's a temporary state\n\tfollowingUserId: false, // does not preserve because it's a temporary state\n\thighlightedUserIds: false, // does not preserve because it's a temporary state\n\tbrush: false, // does not preserve because it's a temporary state\n\tcursor: false, // does not preserve because it's a temporary state\n\tscribbles: false, // does not preserve because it's a temporary state\n\n\tisFocusMode: true, // preserves because it's a user preference\n\tisDebugMode: true, // preserves because it's a user preference\n\tisToolLocked: true, // preserves because it's a user preference\n\texportBackground: true, // preserves because it's a user preference\n\tscreenBounds: true, // preserves because it's capturing the user's screen state\n\tinsets: true, // preserves because it's capturing the user's screen state\n\n\tzoomBrush: false, // does not preserve because it's a temporary state\n\tchatMessage: false, // does not preserve because it's a temporary state\n\tisChatting: false, // does not preserve because it's a temporary state\n\tisPenMode: false, // does not preserve because it's a temporary state\n\n\tisGridMode: true, // preserves because it's a user preference\n\tisFocused: true, // preserves because obviously\n\tdevicePixelRatio: true, // preserves because it captures the user's screen state\n\tisCoarsePointer: true, // preserves because it captures the user's screen state\n\tisHoveringCanvas: false, // does not preserve because it's a temporary state\n\topenMenus: false, // does not preserve because it's a temporary state\n\tisChangingStyle: false, // does not preserve because it's a temporary state\n\tisReadonly: true, // preserves because it's a config option\n\tmeta: false, // does not preserve because who knows what's in there, leave it up to sdk users to save and reinstate\n\tduplicateProps: false, //\n\tcameraState: false, // does not preserve because it's a temporary state\n} as const satisfies { [K in keyof TLInstance]: boolean }\n\n/**\n * Extracts only the properties from a TLInstance that should be preserved\n * between browser sessions, filtering out temporary state.\n *\n * @param val - The TLInstance to filter, or null/undefined\n * @returns A partial TLInstance containing only preservable properties, or null\n *\n * @internal\n */\nexport function pluckPreservingValues(val?: TLInstance | null): null | Partial<TLInstance> {\n\treturn val\n\t\t? (filterEntries(val, (key) => {\n\t\t\t\treturn shouldKeyBePreservedBetweenSessions[key as keyof TLInstance]\n\t\t\t}) as Partial<TLInstance>)\n\t\t: null\n}\n\n/**\n * A unique identifier for TLInstance records.\n *\n * TLInstance IDs are always the constant 'instance:instance' since there\n * is exactly one instance record per browser tab.\n *\n * @public\n */\nexport type TLInstanceId = RecordId<TLInstance>\n\n/**\n * Validator for TLInstanceId values. Ensures the ID follows the correct\n * format for instance records.\n *\n * @example\n * ```ts\n * const isValid = instanceIdValidator.isValid('instance:instance') // true\n * const isValid2 = instanceIdValidator.isValid('invalid') // false\n * ```\n *\n * @public\n */\nexport const instanceIdValidator = idValidator<TLInstanceId>('instance')\n\n/**\n * Creates the record type definition for TLInstance records, including validation\n * and default properties. The function takes a map of available style properties\n * to configure validation for the stylesForNextShape field.\n *\n * @param stylesById - Map of style property IDs to their corresponding StyleProp definitions\n * @returns A configured RecordType for TLInstance records\n *\n * @example\n * ```ts\n * const stylesMap = new Map([['color', DefaultColorStyle]])\n * const InstanceRecordType = createInstanceRecordType(stylesMap)\n *\n * const instance = InstanceRecordType.create({\n * id: 'instance:instance',\n * currentPageId: 'page:page1'\n * })\n * ```\n *\n * @public\n */\nexport function createInstanceRecordType(stylesById: Map<string, StyleProp<unknown>>) {\n\tconst stylesForNextShapeValidators = {} as Record<string, T.Validator<unknown>>\n\tfor (const [id, style] of stylesById) {\n\t\tstylesForNextShapeValidators[id] = T.optional(style)\n\t}\n\n\tconst instanceTypeValidator: T.Validator<TLInstance> = T.model(\n\t\t'instance',\n\t\tT.object({\n\t\t\ttypeName: T.literal('instance'),\n\t\t\tid: idValidator<TLInstanceId>('instance'),\n\t\t\tcurrentPageId: pageIdValidator,\n\t\t\tfollowingUserId: T.string.nullable(),\n\t\t\tbrush: boxModelValidator.nullable(),\n\t\t\topacityForNextShape: opacityValidator,\n\t\t\tstylesForNextShape: T.object(stylesForNextShapeValidators),\n\t\t\tcursor: cursorValidator,\n\t\t\tscribbles: T.arrayOf(scribbleValidator),\n\t\t\tisFocusMode: T.boolean,\n\t\t\tisDebugMode: T.boolean,\n\t\t\tisToolLocked: T.boolean,\n\t\t\texportBackground: T.boolean,\n\t\t\tscreenBounds: boxModelValidator,\n\t\t\tinsets: T.arrayOf(T.boolean),\n\t\t\tzoomBrush: boxModelValidator.nullable(),\n\t\t\tisPenMode: T.boolean,\n\t\t\tisGridMode: T.boolean,\n\t\t\tchatMessage: T.string,\n\t\t\tisChatting: T.boolean,\n\t\t\thighlightedUserIds: T.arrayOf(T.string),\n\t\t\tisFocused: T.boolean,\n\t\t\tdevicePixelRatio: T.number,\n\t\t\tisCoarsePointer: T.boolean,\n\t\t\tisHoveringCanvas: T.boolean.nullable(),\n\t\t\topenMenus: T.arrayOf(T.string),\n\t\t\tisChangingStyle: T.boolean,\n\t\t\tisReadonly: T.boolean,\n\t\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t\t\tduplicateProps: T.object({\n\t\t\t\tshapeIds: T.arrayOf(idValidator<TLShapeId>('shape')),\n\t\t\t\toffset: T.object({\n\t\t\t\t\tx: T.number,\n\t\t\t\t\ty: T.number,\n\t\t\t\t}),\n\t\t\t}).nullable(),\n\t\t\tcameraState: T.literalEnum('idle', 'moving'),\n\t\t})\n\t)\n\n\treturn createRecordType<TLInstance>('instance', {\n\t\tvalidator: instanceTypeValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tcurrentPageId: false,\n\t\t\tmeta: false,\n\n\t\t\tfollowingUserId: true,\n\t\t\topacityForNextShape: true,\n\t\t\tstylesForNextShape: true,\n\t\t\tbrush: true,\n\t\t\tcursor: true,\n\t\t\tscribbles: true,\n\t\t\tisFocusMode: true,\n\t\t\tisDebugMode: true,\n\t\t\tisToolLocked: true,\n\t\t\texportBackground: true,\n\t\t\tscreenBounds: true,\n\t\t\tinsets: true,\n\t\t\tzoomBrush: true,\n\t\t\tisPenMode: true,\n\t\t\tisGridMode: true,\n\t\t\tchatMessage: true,\n\t\t\tisChatting: true,\n\t\t\thighlightedUserIds: true,\n\t\t\tisFocused: true,\n\t\t\tdevicePixelRatio: true,\n\t\t\tisCoarsePointer: true,\n\t\t\tisHoveringCanvas: true,\n\t\t\topenMenus: true,\n\t\t\tisChangingStyle: true,\n\t\t\tisReadonly: true,\n\t\t\tduplicateProps: true,\n\t\t\tcameraState: true,\n\t\t},\n\t}).withDefaultProperties(\n\t\t(): Omit<TLInstance, 'typeName' | 'id' | 'currentPageId'> => ({\n\t\t\tfollowingUserId: null,\n\t\t\topacityForNextShape: 1,\n\t\t\tstylesForNextShape: {},\n\t\t\tbrush: null,\n\t\t\tscribbles: [],\n\t\t\tcursor: {\n\t\t\t\ttype: 'default',\n\t\t\t\trotation: 0,\n\t\t\t},\n\t\t\tisFocusMode: false,\n\t\t\texportBackground: false,\n\t\t\tisDebugMode: false,\n\t\t\tisToolLocked: false,\n\t\t\tscreenBounds: { x: 0, y: 0, w: 1080, h: 720 },\n\t\t\tinsets: [false, false, false, false],\n\t\t\tzoomBrush: null,\n\t\t\tisGridMode: false,\n\t\t\tisPenMode: false,\n\t\t\tchatMessage: '',\n\t\t\tisChatting: false,\n\t\t\thighlightedUserIds: [],\n\t\t\tisFocused: false,\n\t\t\tdevicePixelRatio: typeof window === 'undefined' ? 1 : window.devicePixelRatio,\n\t\t\tisCoarsePointer: false,\n\t\t\tisHoveringCanvas: null,\n\t\t\topenMenus: [] as string[],\n\t\t\tisChangingStyle: false,\n\t\t\tisReadonly: false,\n\t\t\tmeta: {},\n\t\t\tduplicateProps: null,\n\t\t\tcameraState: 'idle',\n\t\t})\n\t)\n}\n\n/**\n * Migration version identifiers for TLInstance records. Each version represents\n * a schema change that requires data transformation when loading older documents.\n *\n * The versions track the evolution of the instance record structure over time,\n * enabling backward and forward compatibility.\n *\n * @public\n */\nexport const instanceVersions = createMigrationIds('com.tldraw.instance', {\n\tAddTransparentExportBgs: 1,\n\tRemoveDialog: 2,\n\tAddToolLockMode: 3,\n\tRemoveExtraPropsForNextShape: 4,\n\tAddLabelColor: 5,\n\tAddFollowingUserId: 6,\n\tRemoveAlignJustify: 7,\n\tAddZoom: 8,\n\tAddVerticalAlign: 9,\n\tAddScribbleDelay: 10,\n\tRemoveUserId: 11,\n\tAddIsPenModeAndIsGridMode: 12,\n\tHoistOpacity: 13,\n\tAddChat: 14,\n\tAddHighlightedUserIds: 15,\n\tReplacePropsForNextShapeWithStylesForNextShape: 16,\n\tAddMeta: 17,\n\tRemoveCursorColor: 18,\n\tAddLonelyProperties: 19,\n\tReadOnlyReadonly: 20,\n\tAddHoveringCanvas: 21,\n\tAddScribbles: 22,\n\tAddInset: 23,\n\tAddDuplicateProps: 24,\n\tRemoveCanMoveCamera: 25,\n\tAddCameraState: 26,\n} as const)\n\n// TODO: rewrite these to use mutation\n\n/**\n * Migration sequence for TLInstance records. Defines how to transform instance\n * records between different schema versions, ensuring data compatibility when\n * loading documents created with different versions of tldraw.\n *\n * Each migration includes an 'up' function to migrate forward and optionally\n * a 'down' function for reverse migration.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migratedInstance = instanceMigrations.migrate(oldInstance, targetVersion)\n * ```\n *\n * @public\n */\nexport const instanceMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance',\n\trecordType: 'instance',\n\tsequence: [\n\t\t{\n\t\t\tid: instanceVersions.AddTransparentExportBgs,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, exportBackground: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveDialog,\n\t\t\tup: ({ dialog: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\n\t\t{\n\t\t\tid: instanceVersions.AddToolLockMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isToolLocked: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveExtraPropsForNextShape,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: Object.fromEntries(\n\t\t\t\t\t\tObject.entries(propsForNextShape).filter(([key]) =>\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'color',\n\t\t\t\t\t\t\t\t'labelColor',\n\t\t\t\t\t\t\t\t'dash',\n\t\t\t\t\t\t\t\t'fill',\n\t\t\t\t\t\t\t\t'size',\n\t\t\t\t\t\t\t\t'font',\n\t\t\t\t\t\t\t\t'align',\n\t\t\t\t\t\t\t\t'verticalAlign',\n\t\t\t\t\t\t\t\t'icon',\n\t\t\t\t\t\t\t\t'geo',\n\t\t\t\t\t\t\t\t'arrowheadStart',\n\t\t\t\t\t\t\t\t'arrowheadEnd',\n\t\t\t\t\t\t\t\t'spline',\n\t\t\t\t\t\t\t].includes(key)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLabelColor,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...propsForNextShape,\n\t\t\t\t\t\tlabelColor: 'black',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddFollowingUserId,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, followingUserId: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveAlignJustify,\n\t\t\tup: (instance: any) => {\n\t\t\t\tlet newAlign = instance.propsForNextShape.align\n\t\t\t\tif (newAlign === 'justify') {\n\t\t\t\t\tnewAlign = 'start'\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\talign: newAlign,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddZoom,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, zoomBrush: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddVerticalAlign,\n\t\t\tup: (instance: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\tverticalAlign: 'middle',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbleDelay,\n\t\t\tup: (instance: any) => {\n\t\t\t\tif (instance.scribble !== null) {\n\t\t\t\t\treturn { ...instance, scribble: { ...instance.scribble, delay: 0 } }\n\t\t\t\t}\n\t\t\t\treturn { ...instance }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveUserId,\n\t\t\tup: ({ userId: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddIsPenModeAndIsGridMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isPenMode: false, isGridMode: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.HoistOpacity,\n\t\t\tup: ({ propsForNextShape: { opacity, ...propsForNextShape }, ...instance }: any) => {\n\t\t\t\treturn { ...instance, opacityForNextShape: Number(opacity ?? '1'), propsForNextShape }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddChat,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, chatMessage: '', isChatting: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHighlightedUserIds,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, highlightedUserIds: [] }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReplacePropsForNextShapeWithStylesForNextShape,\n\t\t\tup: ({ propsForNextShape: _, ...instance }: any) => {\n\t\t\t\treturn { ...instance, stylesForNextShape: {} }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddMeta,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tmeta: {},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCursorColor,\n\t\t\tup: (record: any) => {\n\t\t\t\tconst { color: _, ...cursor } = record.cursor\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcursor,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLonelyProperties,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcanMoveCamera: true,\n\t\t\t\t\tisFocused: false,\n\t\t\t\t\tdevicePixelRatio: 1,\n\t\t\t\t\tisCoarsePointer: false,\n\t\t\t\t\topenMenus: [],\n\t\t\t\t\tisChangingStyle: false,\n\t\t\t\t\tisReadOnly: false,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReadOnlyReadonly,\n\t\t\tup: ({ isReadOnly: _isReadOnly, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisReadonly: _isReadOnly,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHoveringCanvas,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisHoveringCanvas: null,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbles,\n\t\t\tup: ({ scribble: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tscribbles: [],\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddInset,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tinsets: [false, false, false, false],\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ insets: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddDuplicateProps,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tduplicateProps: null,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ duplicateProps: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCanMoveCamera,\n\t\t\tup: ({ canMoveCamera: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (instance) => {\n\t\t\t\treturn { ...instance, canMoveCamera: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddCameraState,\n\t\t\tup: (record) => {\n\t\t\t\treturn { ...record, cameraState: 'idle' }\n\t\t\t},\n\t\t\tdown: ({ cameraState: _, ...record }: any) => {\n\t\t\t\treturn record\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The constant ID used for the singleton TLInstance record.\n *\n * Since each browser tab has exactly one instance, this constant ID\n * is used universally across the application.\n *\n * @example\n * ```ts\n * const instance = store.get(TLINSTANCE_ID)\n * if (instance) {\n * console.log('Current page:', instance.currentPageId)\n * }\n * ```\n *\n * @public\n */\nexport const TLINSTANCE_ID = 'instance:instance' as TLInstanceId\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAMO;AACP,mBAA0C;AAC1C,sBAAkB;AAClB,4BAA4C;AAC5C,0BAA4B;AAC5B,sBAA0C;AAC1C,uBAAgD;AAChD,wBAA8C;AAE9C,oBAA0C;
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { filterEntries, JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorValidator, TLCursor } from '../misc/TLCursor'\nimport { opacityValidator, TLOpacityType } from '../misc/TLOpacity'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { StyleProp } from '../styles/StyleProp'\nimport { pageIdValidator, TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\nimport { TLUserId, userIdValidator } from './TLUser'\n\n/**\n * State that is particular to a single browser tab. The TLInstance record stores\n * all session-specific state including cursor position, selected tools, UI preferences,\n * and temporary interaction state.\n *\n * Each browser tab has exactly one TLInstance record that persists for the duration\n * of the session and tracks the user's current interaction state.\n *\n * @example\n * ```ts\n * const instance: TLInstance = {\n * id: 'instance:instance',\n * typeName: 'instance',\n * currentPageId: 'page:page1',\n * cursor: { type: 'default', rotation: 0 },\n * screenBounds: { x: 0, y: 0, w: 1920, h: 1080 },\n * isFocusMode: false,\n * isGridMode: true\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstance extends BaseRecord<'instance', TLInstanceId> {\n\tcurrentPageId: TLPageId\n\topacityForNextShape: TLOpacityType\n\tstylesForNextShape: Record<string, unknown>\n\tfollowingUserId: TLUserId | null\n\thighlightedUserIds: TLUserId[]\n\tbrush: BoxModel | null\n\tcursor: TLCursor\n\tscribbles: TLScribble[]\n\tisFocusMode: boolean\n\tisDebugMode: boolean\n\tisToolLocked: boolean\n\texportBackground: boolean\n\tscreenBounds: BoxModel\n\tinsets: boolean[]\n\tzoomBrush: BoxModel | null\n\tchatMessage: string\n\tisChatting: boolean\n\tisPenMode: boolean\n\tisGridMode: boolean\n\tisFocused: boolean\n\tdevicePixelRatio: number\n\t/**\n\t * This is whether the primary input mechanism includes a pointing device of limited accuracy,\n\t * such as a finger on a touchscreen.\n\t */\n\tisCoarsePointer: boolean\n\t/**\n\t * Will be null if the pointer doesn't support hovering (e.g. touch), but true or false\n\t * otherwise\n\t */\n\tisHoveringCanvas: boolean | null\n\topenMenus: string[]\n\tisChangingStyle: boolean\n\tisReadonly: boolean\n\tmeta: JsonObject\n\tduplicateProps: {\n\t\tshapeIds: TLShapeId[]\n\t\toffset: {\n\t\t\tx: number\n\t\t\ty: number\n\t\t}\n\t} | null\n\t/**\n\t * Whether the camera is currently moving or idle. Used to optimize rendering\n\t * and hit-testing during panning/zooming.\n\t */\n\tcameraState: 'idle' | 'moving'\n}\n\n/**\n * Configuration object defining which TLInstance properties should be preserved\n * when loading snapshots across browser sessions. Properties marked as `true`\n * represent user preferences that should persist, while `false` indicates\n * temporary state that should reset.\n *\n * @internal\n */\nexport const shouldKeyBePreservedBetweenSessions = {\n\t// This object defines keys that should be preserved across calls to loadSnapshot()\n\n\tid: false, // meta\n\ttypeName: false, // meta\n\n\tcurrentPageId: false, // does not preserve because who knows if the page still exists\n\topacityForNextShape: false, // does not preserve because it's a temporary state\n\tstylesForNextShape: false, // does not preserve because it's a temporary state\n\tfollowingUserId: false, // does not preserve because it's a temporary state\n\thighlightedUserIds: false, // does not preserve because it's a temporary state\n\tbrush: false, // does not preserve because it's a temporary state\n\tcursor: false, // does not preserve because it's a temporary state\n\tscribbles: false, // does not preserve because it's a temporary state\n\n\tisFocusMode: true, // preserves because it's a user preference\n\tisDebugMode: true, // preserves because it's a user preference\n\tisToolLocked: true, // preserves because it's a user preference\n\texportBackground: true, // preserves because it's a user preference\n\tscreenBounds: true, // preserves because it's capturing the user's screen state\n\tinsets: true, // preserves because it's capturing the user's screen state\n\n\tzoomBrush: false, // does not preserve because it's a temporary state\n\tchatMessage: false, // does not preserve because it's a temporary state\n\tisChatting: false, // does not preserve because it's a temporary state\n\tisPenMode: false, // does not preserve because it's a temporary state\n\n\tisGridMode: true, // preserves because it's a user preference\n\tisFocused: true, // preserves because obviously\n\tdevicePixelRatio: true, // preserves because it captures the user's screen state\n\tisCoarsePointer: true, // preserves because it captures the user's screen state\n\tisHoveringCanvas: false, // does not preserve because it's a temporary state\n\topenMenus: false, // does not preserve because it's a temporary state\n\tisChangingStyle: false, // does not preserve because it's a temporary state\n\tisReadonly: true, // preserves because it's a config option\n\tmeta: false, // does not preserve because who knows what's in there, leave it up to sdk users to save and reinstate\n\tduplicateProps: false, //\n\tcameraState: false, // does not preserve because it's a temporary state\n} as const satisfies { [K in keyof TLInstance]: boolean }\n\n/**\n * Extracts only the properties from a TLInstance that should be preserved\n * between browser sessions, filtering out temporary state.\n *\n * @param val - The TLInstance to filter, or null/undefined\n * @returns A partial TLInstance containing only preservable properties, or null\n *\n * @internal\n */\nexport function pluckPreservingValues(val?: TLInstance | null): null | Partial<TLInstance> {\n\treturn val\n\t\t? (filterEntries(val, (key) => {\n\t\t\t\treturn shouldKeyBePreservedBetweenSessions[key as keyof TLInstance]\n\t\t\t}) as Partial<TLInstance>)\n\t\t: null\n}\n\n/**\n * A unique identifier for TLInstance records.\n *\n * TLInstance IDs are always the constant 'instance:instance' since there\n * is exactly one instance record per browser tab.\n *\n * @public\n */\nexport type TLInstanceId = RecordId<TLInstance>\n\n/**\n * Validator for TLInstanceId values. Ensures the ID follows the correct\n * format for instance records.\n *\n * @example\n * ```ts\n * const isValid = instanceIdValidator.isValid('instance:instance') // true\n * const isValid2 = instanceIdValidator.isValid('invalid') // false\n * ```\n *\n * @public\n */\nexport const instanceIdValidator = idValidator<TLInstanceId>('instance')\n\n/**\n * Creates the record type definition for TLInstance records, including validation\n * and default properties. The function takes a map of available style properties\n * to configure validation for the stylesForNextShape field.\n *\n * @param stylesById - Map of style property IDs to their corresponding StyleProp definitions\n * @returns A configured RecordType for TLInstance records\n *\n * @example\n * ```ts\n * const stylesMap = new Map([['color', DefaultColorStyle]])\n * const InstanceRecordType = createInstanceRecordType(stylesMap)\n *\n * const instance = InstanceRecordType.create({\n * id: 'instance:instance',\n * currentPageId: 'page:page1'\n * })\n * ```\n *\n * @public\n */\nexport function createInstanceRecordType(stylesById: Map<string, StyleProp<unknown>>) {\n\tconst stylesForNextShapeValidators = {} as Record<string, T.Validator<unknown>>\n\tfor (const [id, style] of stylesById) {\n\t\tstylesForNextShapeValidators[id] = T.optional(style)\n\t}\n\n\tconst instanceTypeValidator: T.Validator<TLInstance> = T.model(\n\t\t'instance',\n\t\tT.object({\n\t\t\ttypeName: T.literal('instance'),\n\t\t\tid: idValidator<TLInstanceId>('instance'),\n\t\t\tcurrentPageId: pageIdValidator,\n\t\t\tfollowingUserId: userIdValidator.nullable(),\n\t\t\tbrush: boxModelValidator.nullable(),\n\t\t\topacityForNextShape: opacityValidator,\n\t\t\tstylesForNextShape: T.object(stylesForNextShapeValidators),\n\t\t\tcursor: cursorValidator,\n\t\t\tscribbles: T.arrayOf(scribbleValidator),\n\t\t\tisFocusMode: T.boolean,\n\t\t\tisDebugMode: T.boolean,\n\t\t\tisToolLocked: T.boolean,\n\t\t\texportBackground: T.boolean,\n\t\t\tscreenBounds: boxModelValidator,\n\t\t\tinsets: T.arrayOf(T.boolean),\n\t\t\tzoomBrush: boxModelValidator.nullable(),\n\t\t\tisPenMode: T.boolean,\n\t\t\tisGridMode: T.boolean,\n\t\t\tchatMessage: T.string,\n\t\t\tisChatting: T.boolean,\n\t\t\thighlightedUserIds: T.arrayOf(userIdValidator),\n\t\t\tisFocused: T.boolean,\n\t\t\tdevicePixelRatio: T.number,\n\t\t\tisCoarsePointer: T.boolean,\n\t\t\tisHoveringCanvas: T.boolean.nullable(),\n\t\t\topenMenus: T.arrayOf(T.string),\n\t\t\tisChangingStyle: T.boolean,\n\t\t\tisReadonly: T.boolean,\n\t\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t\t\tduplicateProps: T.object({\n\t\t\t\tshapeIds: T.arrayOf(idValidator<TLShapeId>('shape')),\n\t\t\t\toffset: T.object({\n\t\t\t\t\tx: T.number,\n\t\t\t\t\ty: T.number,\n\t\t\t\t}),\n\t\t\t}).nullable(),\n\t\t\tcameraState: T.literalEnum('idle', 'moving'),\n\t\t})\n\t)\n\n\treturn createRecordType<TLInstance>('instance', {\n\t\tvalidator: instanceTypeValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tcurrentPageId: false,\n\t\t\tmeta: false,\n\n\t\t\tfollowingUserId: true,\n\t\t\topacityForNextShape: true,\n\t\t\tstylesForNextShape: true,\n\t\t\tbrush: true,\n\t\t\tcursor: true,\n\t\t\tscribbles: true,\n\t\t\tisFocusMode: true,\n\t\t\tisDebugMode: true,\n\t\t\tisToolLocked: true,\n\t\t\texportBackground: true,\n\t\t\tscreenBounds: true,\n\t\t\tinsets: true,\n\t\t\tzoomBrush: true,\n\t\t\tisPenMode: true,\n\t\t\tisGridMode: true,\n\t\t\tchatMessage: true,\n\t\t\tisChatting: true,\n\t\t\thighlightedUserIds: true,\n\t\t\tisFocused: true,\n\t\t\tdevicePixelRatio: true,\n\t\t\tisCoarsePointer: true,\n\t\t\tisHoveringCanvas: true,\n\t\t\topenMenus: true,\n\t\t\tisChangingStyle: true,\n\t\t\tisReadonly: true,\n\t\t\tduplicateProps: true,\n\t\t\tcameraState: true,\n\t\t},\n\t}).withDefaultProperties(\n\t\t(): Omit<TLInstance, 'typeName' | 'id' | 'currentPageId'> => ({\n\t\t\tfollowingUserId: null,\n\t\t\topacityForNextShape: 1,\n\t\t\tstylesForNextShape: {},\n\t\t\tbrush: null,\n\t\t\tscribbles: [],\n\t\t\tcursor: {\n\t\t\t\ttype: 'default',\n\t\t\t\trotation: 0,\n\t\t\t},\n\t\t\tisFocusMode: false,\n\t\t\texportBackground: false,\n\t\t\tisDebugMode: false,\n\t\t\tisToolLocked: false,\n\t\t\tscreenBounds: { x: 0, y: 0, w: 1080, h: 720 },\n\t\t\tinsets: [false, false, false, false],\n\t\t\tzoomBrush: null,\n\t\t\tisGridMode: false,\n\t\t\tisPenMode: false,\n\t\t\tchatMessage: '',\n\t\t\tisChatting: false,\n\t\t\thighlightedUserIds: [],\n\t\t\tisFocused: false,\n\t\t\tdevicePixelRatio: typeof window === 'undefined' ? 1 : window.devicePixelRatio,\n\t\t\tisCoarsePointer: false,\n\t\t\tisHoveringCanvas: null,\n\t\t\topenMenus: [] as string[],\n\t\t\tisChangingStyle: false,\n\t\t\tisReadonly: false,\n\t\t\tmeta: {},\n\t\t\tduplicateProps: null,\n\t\t\tcameraState: 'idle',\n\t\t})\n\t)\n}\n\n/**\n * Migration version identifiers for TLInstance records. Each version represents\n * a schema change that requires data transformation when loading older documents.\n *\n * The versions track the evolution of the instance record structure over time,\n * enabling backward and forward compatibility.\n *\n * @public\n */\nexport const instanceVersions = createMigrationIds('com.tldraw.instance', {\n\tAddTransparentExportBgs: 1,\n\tRemoveDialog: 2,\n\tAddToolLockMode: 3,\n\tRemoveExtraPropsForNextShape: 4,\n\tAddLabelColor: 5,\n\tAddFollowingUserId: 6,\n\tRemoveAlignJustify: 7,\n\tAddZoom: 8,\n\tAddVerticalAlign: 9,\n\tAddScribbleDelay: 10,\n\tRemoveUserId: 11,\n\tAddIsPenModeAndIsGridMode: 12,\n\tHoistOpacity: 13,\n\tAddChat: 14,\n\tAddHighlightedUserIds: 15,\n\tReplacePropsForNextShapeWithStylesForNextShape: 16,\n\tAddMeta: 17,\n\tRemoveCursorColor: 18,\n\tAddLonelyProperties: 19,\n\tReadOnlyReadonly: 20,\n\tAddHoveringCanvas: 21,\n\tAddScribbles: 22,\n\tAddInset: 23,\n\tAddDuplicateProps: 24,\n\tRemoveCanMoveCamera: 25,\n\tAddCameraState: 26,\n} as const)\n\n// TODO: rewrite these to use mutation\n\n/**\n * Migration sequence for TLInstance records. Defines how to transform instance\n * records between different schema versions, ensuring data compatibility when\n * loading documents created with different versions of tldraw.\n *\n * Each migration includes an 'up' function to migrate forward and optionally\n * a 'down' function for reverse migration.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migratedInstance = instanceMigrations.migrate(oldInstance, targetVersion)\n * ```\n *\n * @public\n */\nexport const instanceMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance',\n\trecordType: 'instance',\n\tsequence: [\n\t\t{\n\t\t\tid: instanceVersions.AddTransparentExportBgs,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, exportBackground: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveDialog,\n\t\t\tup: ({ dialog: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\n\t\t{\n\t\t\tid: instanceVersions.AddToolLockMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isToolLocked: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveExtraPropsForNextShape,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: Object.fromEntries(\n\t\t\t\t\t\tObject.entries(propsForNextShape).filter(([key]) =>\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'color',\n\t\t\t\t\t\t\t\t'labelColor',\n\t\t\t\t\t\t\t\t'dash',\n\t\t\t\t\t\t\t\t'fill',\n\t\t\t\t\t\t\t\t'size',\n\t\t\t\t\t\t\t\t'font',\n\t\t\t\t\t\t\t\t'align',\n\t\t\t\t\t\t\t\t'verticalAlign',\n\t\t\t\t\t\t\t\t'icon',\n\t\t\t\t\t\t\t\t'geo',\n\t\t\t\t\t\t\t\t'arrowheadStart',\n\t\t\t\t\t\t\t\t'arrowheadEnd',\n\t\t\t\t\t\t\t\t'spline',\n\t\t\t\t\t\t\t].includes(key)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLabelColor,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...propsForNextShape,\n\t\t\t\t\t\tlabelColor: 'black',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddFollowingUserId,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, followingUserId: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveAlignJustify,\n\t\t\tup: (instance: any) => {\n\t\t\t\tlet newAlign = instance.propsForNextShape.align\n\t\t\t\tif (newAlign === 'justify') {\n\t\t\t\t\tnewAlign = 'start'\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\talign: newAlign,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddZoom,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, zoomBrush: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddVerticalAlign,\n\t\t\tup: (instance: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\tverticalAlign: 'middle',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbleDelay,\n\t\t\tup: (instance: any) => {\n\t\t\t\tif (instance.scribble !== null) {\n\t\t\t\t\treturn { ...instance, scribble: { ...instance.scribble, delay: 0 } }\n\t\t\t\t}\n\t\t\t\treturn { ...instance }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveUserId,\n\t\t\tup: ({ userId: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddIsPenModeAndIsGridMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isPenMode: false, isGridMode: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.HoistOpacity,\n\t\t\tup: ({ propsForNextShape: { opacity, ...propsForNextShape }, ...instance }: any) => {\n\t\t\t\treturn { ...instance, opacityForNextShape: Number(opacity ?? '1'), propsForNextShape }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddChat,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, chatMessage: '', isChatting: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHighlightedUserIds,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, highlightedUserIds: [] }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReplacePropsForNextShapeWithStylesForNextShape,\n\t\t\tup: ({ propsForNextShape: _, ...instance }: any) => {\n\t\t\t\treturn { ...instance, stylesForNextShape: {} }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddMeta,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tmeta: {},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCursorColor,\n\t\t\tup: (record: any) => {\n\t\t\t\tconst { color: _, ...cursor } = record.cursor\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcursor,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLonelyProperties,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcanMoveCamera: true,\n\t\t\t\t\tisFocused: false,\n\t\t\t\t\tdevicePixelRatio: 1,\n\t\t\t\t\tisCoarsePointer: false,\n\t\t\t\t\topenMenus: [],\n\t\t\t\t\tisChangingStyle: false,\n\t\t\t\t\tisReadOnly: false,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReadOnlyReadonly,\n\t\t\tup: ({ isReadOnly: _isReadOnly, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisReadonly: _isReadOnly,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHoveringCanvas,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisHoveringCanvas: null,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbles,\n\t\t\tup: ({ scribble: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tscribbles: [],\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddInset,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tinsets: [false, false, false, false],\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ insets: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddDuplicateProps,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tduplicateProps: null,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ duplicateProps: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCanMoveCamera,\n\t\t\tup: ({ canMoveCamera: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (instance) => {\n\t\t\t\treturn { ...instance, canMoveCamera: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddCameraState,\n\t\t\tup: (record) => {\n\t\t\t\treturn { ...record, cameraState: 'idle' }\n\t\t\t},\n\t\t\tdown: ({ cameraState: _, ...record }: any) => {\n\t\t\t\treturn record\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The constant ID used for the singleton TLInstance record.\n *\n * Since each browser tab has exactly one instance, this constant ID\n * is used universally across the application.\n *\n * @example\n * ```ts\n * const instance = store.get(TLINSTANCE_ID)\n * if (instance) {\n * console.log('Current page:', instance.currentPageId)\n * }\n * ```\n *\n * @public\n */\nexport const TLINSTANCE_ID = 'instance:instance' as TLInstanceId\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAMO;AACP,mBAA0C;AAC1C,sBAAkB;AAClB,4BAA4C;AAC5C,0BAA4B;AAC5B,sBAA0C;AAC1C,uBAAgD;AAChD,wBAA8C;AAE9C,oBAA0C;AAE1C,oBAA0C;AAmFnC,MAAM,sCAAsC;AAAA;AAAA,EAGlD,IAAI;AAAA;AAAA,EACJ,UAAU;AAAA;AAAA,EAEV,eAAe;AAAA;AAAA,EACf,qBAAqB;AAAA;AAAA,EACrB,oBAAoB;AAAA;AAAA,EACpB,iBAAiB;AAAA;AAAA,EACjB,oBAAoB;AAAA;AAAA,EACpB,OAAO;AAAA;AAAA,EACP,QAAQ;AAAA;AAAA,EACR,WAAW;AAAA;AAAA,EAEX,aAAa;AAAA;AAAA,EACb,aAAa;AAAA;AAAA,EACb,cAAc;AAAA;AAAA,EACd,kBAAkB;AAAA;AAAA,EAClB,cAAc;AAAA;AAAA,EACd,QAAQ;AAAA;AAAA,EAER,WAAW;AAAA;AAAA,EACX,aAAa;AAAA;AAAA,EACb,YAAY;AAAA;AAAA,EACZ,WAAW;AAAA;AAAA,EAEX,YAAY;AAAA;AAAA,EACZ,WAAW;AAAA;AAAA,EACX,kBAAkB;AAAA;AAAA,EAClB,iBAAiB;AAAA;AAAA,EACjB,kBAAkB;AAAA;AAAA,EAClB,WAAW;AAAA;AAAA,EACX,iBAAiB;AAAA;AAAA,EACjB,YAAY;AAAA;AAAA,EACZ,MAAM;AAAA;AAAA,EACN,gBAAgB;AAAA;AAAA,EAChB,aAAa;AAAA;AACd;AAWO,SAAS,sBAAsB,KAAqD;AAC1F,SAAO,UACH,4BAAc,KAAK,CAAC,QAAQ;AAC7B,WAAO,oCAAoC,GAAuB;AAAA,EACnE,CAAC,IACA;AACJ;AAwBO,MAAM,0BAAsB,iCAA0B,UAAU;AAuBhE,SAAS,yBAAyB,YAA6C;AACrF,QAAM,+BAA+B,CAAC;AACtC,aAAW,CAAC,IAAI,KAAK,KAAK,YAAY;AACrC,iCAA6B,EAAE,IAAI,kBAAE,SAAS,KAAK;AAAA,EACpD;AAEA,QAAM,wBAAiD,kBAAE;AAAA,IACxD;AAAA,IACA,kBAAE,OAAO;AAAA,MACR,UAAU,kBAAE,QAAQ,UAAU;AAAA,MAC9B,QAAI,iCAA0B,UAAU;AAAA,MACxC,eAAe;AAAA,MACf,iBAAiB,8BAAgB,SAAS;AAAA,MAC1C,OAAO,wCAAkB,SAAS;AAAA,MAClC,qBAAqB;AAAA,MACrB,oBAAoB,kBAAE,OAAO,4BAA4B;AAAA,MACzD,QAAQ;AAAA,MACR,WAAW,kBAAE,QAAQ,mCAAiB;AAAA,MACtC,aAAa,kBAAE;AAAA,MACf,aAAa,kBAAE;AAAA,MACf,cAAc,kBAAE;AAAA,MAChB,kBAAkB,kBAAE;AAAA,MACpB,cAAc;AAAA,MACd,QAAQ,kBAAE,QAAQ,kBAAE,OAAO;AAAA,MAC3B,WAAW,wCAAkB,SAAS;AAAA,MACtC,WAAW,kBAAE;AAAA,MACb,YAAY,kBAAE;AAAA,MACd,aAAa,kBAAE;AAAA,MACf,YAAY,kBAAE;AAAA,MACd,oBAAoB,kBAAE,QAAQ,6BAAe;AAAA,MAC7C,WAAW,kBAAE;AAAA,MACb,kBAAkB,kBAAE;AAAA,MACpB,iBAAiB,kBAAE;AAAA,MACnB,kBAAkB,kBAAE,QAAQ,SAAS;AAAA,MACrC,WAAW,kBAAE,QAAQ,kBAAE,MAAM;AAAA,MAC7B,iBAAiB,kBAAE;AAAA,MACnB,YAAY,kBAAE;AAAA,MACd,MAAM,kBAAE;AAAA,MACR,gBAAgB,kBAAE,OAAO;AAAA,QACxB,UAAU,kBAAE,YAAQ,iCAAuB,OAAO,CAAC;AAAA,QACnD,QAAQ,kBAAE,OAAO;AAAA,UAChB,GAAG,kBAAE;AAAA,UACL,GAAG,kBAAE;AAAA,QACN,CAAC;AAAA,MACF,CAAC,EAAE,SAAS;AAAA,MACZ,aAAa,kBAAE,YAAY,QAAQ,QAAQ;AAAA,IAC5C,CAAC;AAAA,EACF;AAEA,aAAO,+BAA6B,YAAY;AAAA,IAC/C,WAAW;AAAA,IACX,OAAO;AAAA,IACP,eAAe;AAAA,MACd,eAAe;AAAA,MACf,MAAM;AAAA,MAEN,iBAAiB;AAAA,MACjB,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,MACpB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,aAAa;AAAA,MACb,aAAa;AAAA,MACb,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,oBAAoB;AAAA,MACpB,WAAW;AAAA,MACX,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,IACd;AAAA,EACD,CAAC,EAAE;AAAA,IACF,OAA8D;AAAA,MAC7D,iBAAiB;AAAA,MACjB,qBAAqB;AAAA,MACrB,oBAAoB,CAAC;AAAA,MACrB,OAAO;AAAA,MACP,WAAW,CAAC;AAAA,MACZ,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACX;AAAA,MACA,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,cAAc,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI;AAAA,MAC5C,QAAQ,CAAC,OAAO,OAAO,OAAO,KAAK;AAAA,MACnC,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,oBAAoB,CAAC;AAAA,MACrB,WAAW;AAAA,MACX,kBAAkB,OAAO,WAAW,cAAc,IAAI,OAAO;AAAA,MAC7D,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,WAAW,CAAC;AAAA,MACZ,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,MAAM,CAAC;AAAA,MACP,gBAAgB;AAAA,MAChB,aAAa;AAAA,IACd;AAAA,EACD;AACD;AAWO,MAAM,uBAAmB,iCAAmB,uBAAuB;AAAA,EACzE,yBAAyB;AAAA,EACzB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,8BAA8B;AAAA,EAC9B,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,SAAS;AAAA,EACT,uBAAuB;AAAA,EACvB,gDAAgD;AAAA,EAChD,SAAS;AAAA,EACT,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,gBAAgB;AACjB,CAAU;AAoBH,MAAM,yBAAqB,4CAA8B;AAAA,EAC/D,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,IACT;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAa;AACjB,eAAO,EAAE,GAAG,UAAU,kBAAkB,KAAK;AAAA,MAC9C;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,QAAQ,GAAG,GAAG,SAAS,MAAW;AACxC,eAAO;AAAA,MACR;AAAA,IACD;AAAA,IAEA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAa;AACjB,eAAO,EAAE,GAAG,UAAU,cAAc,MAAM;AAAA,MAC3C;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,mBAAmB,GAAG,SAAS,MAAW;AAChD,eAAO;AAAA,UACN,GAAG;AAAA,UACH,mBAAmB,OAAO;AAAA,YACzB,OAAO,QAAQ,iBAAiB,EAAE;AAAA,cAAO,CAAC,CAAC,GAAG,MAC7C;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACD,EAAE,SAAS,GAAG;AAAA,YACf;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,mBAAmB,GAAG,SAAS,MAAW;AAChD,eAAO;AAAA,UACN,GAAG;AAAA,UACH,mBAAmB;AAAA,YAClB,GAAG;AAAA,YACH,YAAY;AAAA,UACb;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAa;AACjB,eAAO,EAAE,GAAG,UAAU,iBAAiB,KAAK;AAAA,MAC7C;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAkB;AACtB,YAAI,WAAW,SAAS,kBAAkB;AAC1C,YAAI,aAAa,WAAW;AAC3B,qBAAW;AAAA,QACZ;AAEA,eAAO;AAAA,UACN,GAAG;AAAA,UACH,mBAAmB;AAAA,YAClB,GAAG,SAAS;AAAA,YACZ,OAAO;AAAA,UACR;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAa;AACjB,eAAO,EAAE,GAAG,UAAU,WAAW,KAAK;AAAA,MACvC;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAkB;AACtB,eAAO;AAAA,UACN,GAAG;AAAA,UACH,mBAAmB;AAAA,YAClB,GAAG,SAAS;AAAA,YACZ,eAAe;AAAA,UAChB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAkB;AACtB,YAAI,SAAS,aAAa,MAAM;AAC/B,iBAAO,EAAE,GAAG,UAAU,UAAU,EAAE,GAAG,SAAS,UAAU,OAAO,EAAE,EAAE;AAAA,QACpE;AACA,eAAO,EAAE,GAAG,SAAS;AAAA,MACtB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,QAAQ,GAAG,GAAG,SAAS,MAAW;AACxC,eAAO;AAAA,MACR;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAa;AACjB,eAAO,EAAE,GAAG,UAAU,WAAW,OAAO,YAAY,MAAM;AAAA,MAC3D;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,mBAAmB,EAAE,SAAS,GAAG,kBAAkB,GAAG,GAAG,SAAS,MAAW;AACnF,eAAO,EAAE,GAAG,UAAU,qBAAqB,OAAO,WAAW,GAAG,GAAG,kBAAkB;AAAA,MACtF;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAa;AACjB,eAAO,EAAE,GAAG,UAAU,aAAa,IAAI,YAAY,MAAM;AAAA,MAC1D;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,aAAa;AACjB,eAAO,EAAE,GAAG,UAAU,oBAAoB,CAAC,EAAE;AAAA,MAC9C;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,mBAAmB,GAAG,GAAG,SAAS,MAAW;AACnD,eAAO,EAAE,GAAG,UAAU,oBAAoB,CAAC,EAAE;AAAA,MAC9C;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,WAAW;AACf,eAAO;AAAA,UACN,GAAG;AAAA,UACH,MAAM,CAAC;AAAA,QACR;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,WAAgB;AACpB,cAAM,EAAE,OAAO,GAAG,GAAG,OAAO,IAAI,OAAO;AACvC,eAAO;AAAA,UACN,GAAG;AAAA,UACH;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,WAAW;AACf,eAAO;AAAA,UACN,GAAG;AAAA,UACH,eAAe;AAAA,UACf,WAAW;AAAA,UACX,kBAAkB;AAAA,UAClB,iBAAiB;AAAA,UACjB,WAAW,CAAC;AAAA,UACZ,iBAAiB;AAAA,UACjB,YAAY;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,YAAY,aAAa,GAAG,OAAO,MAAW;AACpD,eAAO;AAAA,UACN,GAAG;AAAA,UACH,YAAY;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,WAAW;AACf,eAAO;AAAA,UACN,GAAG;AAAA,UACH,kBAAkB;AAAA,QACnB;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,UAAU,GAAG,GAAG,OAAO,MAAW;AACxC,eAAO;AAAA,UACN,GAAG;AAAA,UACH,WAAW,CAAC;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,WAAW;AACf,eAAO;AAAA,UACN,GAAG;AAAA,UACH,QAAQ,CAAC,OAAO,OAAO,OAAO,KAAK;AAAA,QACpC;AAAA,MACD;AAAA,MACA,MAAM,CAAC,EAAE,QAAQ,GAAG,GAAG,OAAO,MAAW;AACxC,eAAO;AAAA,UACN,GAAG;AAAA,QACJ;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,WAAW;AACf,eAAO;AAAA,UACN,GAAG;AAAA,UACH,gBAAgB;AAAA,QACjB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,EAAE,gBAAgB,GAAG,GAAG,OAAO,MAAW;AAChD,eAAO;AAAA,UACN,GAAG;AAAA,QACJ;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,EAAE,eAAe,GAAG,GAAG,OAAO,MAAW;AAC7C,eAAO;AAAA,UACN,GAAG;AAAA,QACJ;AAAA,MACD;AAAA,MACA,MAAM,CAAC,aAAa;AACnB,eAAO,EAAE,GAAG,UAAU,eAAe,KAAK;AAAA,MAC3C;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,iBAAiB;AAAA,MACrB,IAAI,CAAC,WAAW;AACf,eAAO,EAAE,GAAG,QAAQ,aAAa,OAAO;AAAA,MACzC;AAAA,MACA,MAAM,CAAC,EAAE,aAAa,GAAG,GAAG,OAAO,MAAW;AAC7C,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAkBM,MAAM,gBAAgB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -129,7 +129,11 @@ const InstancePageStateRecordType = (0, import_store.createRecordType)(
|
|
|
129
129
|
ephemeralKeys: {
|
|
130
130
|
pageId: false,
|
|
131
131
|
selectedShapeIds: false,
|
|
132
|
-
editingShapeId:
|
|
132
|
+
// editingShapeId is set with `history: 'ignore'`, so entering the editing
|
|
133
|
+
// state is never undoable. Marking it ephemeral keeps undo/redo from
|
|
134
|
+
// reapplying a stale editingShapeId (e.g. after a shape it pointed at was
|
|
135
|
+
// deleted), which could leave the editor pointing at a missing shape.
|
|
136
|
+
editingShapeId: true,
|
|
133
137
|
croppingShapeId: false,
|
|
134
138
|
meta: false,
|
|
135
139
|
hintingShapeIds: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/records/TLPageState.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { shapeIdValidator } from '../shapes/TLBaseShape'\nimport { pageIdValidator, TLPage } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * State that is unique to a particular page within a particular browser tab.\n * This record tracks all page-specific interaction state including selected shapes,\n * editing state, hover state, and other transient UI state that is tied to\n * both a specific page and a specific browser session.\n *\n * Each combination of page and browser tab has its own TLInstancePageState record.\n *\n * @example\n * ```ts\n * const pageState: TLInstancePageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1', 'shape:circle2'],\n * hoveredShapeId: 'shape:text3',\n * editingShapeId: null,\n * focusedGroupId: null\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePageState extends BaseRecord<\n\t'instance_page_state',\n\tTLInstancePageStateId\n> {\n\tpageId: RecordId<TLPage>\n\tselectedShapeIds: TLShapeId[]\n\thintingShapeIds: TLShapeId[]\n\terasingShapeIds: TLShapeId[]\n\thoveredShapeId: TLShapeId | null\n\teditingShapeId: TLShapeId | null\n\tcroppingShapeId: TLShapeId | null\n\tfocusedGroupId: TLShapeId | null\n\tmeta: JsonObject\n}\n\n/**\n * Runtime validator for TLInstancePageState records. Validates the structure\n * and types of all instance page state properties to ensure data integrity.\n *\n * @example\n * ```ts\n * const pageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1'],\n * // ... other properties\n * }\n * const isValid = instancePageStateValidator.isValid(pageState) // true\n * ```\n *\n * @public\n */\nexport const instancePageStateValidator: T.Validator<TLInstancePageState> = T.model(\n\t'instance_page_state',\n\tT.object({\n\t\ttypeName: T.literal('instance_page_state'),\n\t\tid: idValidator<TLInstancePageStateId>('instance_page_state'),\n\t\tpageId: pageIdValidator,\n\t\tselectedShapeIds: T.arrayOf(shapeIdValidator),\n\t\thintingShapeIds: T.arrayOf(shapeIdValidator),\n\t\terasingShapeIds: T.arrayOf(shapeIdValidator),\n\t\thoveredShapeId: shapeIdValidator.nullable(),\n\t\teditingShapeId: shapeIdValidator.nullable(),\n\t\tcroppingShapeId: shapeIdValidator.nullable(),\n\t\tfocusedGroupId: shapeIdValidator.nullable(),\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n)\n\n/**\n * Migration version identifiers for TLInstancePageState records. Each version\n * represents a schema change that requires data transformation when loading\n * older documents.\n *\n * @public\n */\nexport const instancePageStateVersions = createMigrationIds('com.tldraw.instance_page_state', {\n\tAddCroppingId: 1,\n\tRemoveInstanceIdAndCameraId: 2,\n\tAddMeta: 3,\n\tRenameProperties: 4,\n\tRenamePropertiesAgain: 5,\n} as const)\n\n/**\n * Migration sequence for TLInstancePageState records. Defines how to transform\n * instance page state records between different schema versions, ensuring data\n * compatibility when loading documents created with different versions.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migrated = instancePageStateMigrations.migrate(oldState, targetVersion)\n * ```\n *\n * @public\n */\nexport const instancePageStateMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance_page_state',\n\trecordType: 'instance_page_state',\n\tsequence: [\n\t\t{\n\t\t\tid: instancePageStateVersions.AddCroppingId,\n\t\t\tup(instance: any) {\n\t\t\t\tinstance.croppingShapeId = null\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RemoveInstanceIdAndCameraId,\n\t\t\tup(instance: any) {\n\t\t\t\tdelete instance.instanceId\n\t\t\t\tdelete instance.cameraId\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.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: instancePageStateVersions.RenameProperties,\n\t\t\t// this migration is cursed: it was written wrong and doesn't do anything.\n\t\t\t// rather than replace it, I've added another migration below that fixes it.\n\t\t\tup: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RenamePropertiesAgain,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.selectedShapeIds = record.selectedIds\n\t\t\t\tdelete record.selectedIds\n\t\t\t\trecord.hintingShapeIds = record.hintingIds\n\t\t\t\tdelete record.hintingIds\n\t\t\t\trecord.erasingShapeIds = record.erasingIds\n\t\t\t\tdelete record.erasingIds\n\t\t\t\trecord.hoveredShapeId = record.hoveredId\n\t\t\t\tdelete record.hoveredId\n\t\t\t\trecord.editingShapeId = record.editingId\n\t\t\t\tdelete record.editingId\n\t\t\t\trecord.croppingShapeId = record.croppingShapeId ?? record.croppingId ?? null\n\t\t\t\tdelete record.croppingId\n\t\t\t\trecord.focusedGroupId = record.focusLayerId\n\t\t\t\tdelete record.focusLayerId\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\trecord.selectedIds = record.selectedShapeIds\n\t\t\t\tdelete record.selectedShapeIds\n\t\t\t\trecord.hintingIds = record.hintingShapeIds\n\t\t\t\tdelete record.hintingShapeIds\n\t\t\t\trecord.erasingIds = record.erasingShapeIds\n\t\t\t\tdelete record.erasingShapeIds\n\t\t\t\trecord.hoveredId = record.hoveredShapeId\n\t\t\t\tdelete record.hoveredShapeId\n\t\t\t\trecord.editingId = record.editingShapeId\n\t\t\t\tdelete record.editingShapeId\n\t\t\t\trecord.croppingId = record.croppingShapeId\n\t\t\t\tdelete record.croppingShapeId\n\t\t\t\trecord.focusLayerId = record.focusedGroupId\n\t\t\t\tdelete record.focusedGroupId\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The RecordType definition for TLInstancePageState records. Defines validation,\n * scope, and default properties for instance page state records.\n *\n * Instance page states are scoped to the session level, meaning they are\n * specific to a browser tab and don't persist across sessions or sync\n * in collaborative environments.\n *\n * @example\n * ```ts\n * const pageState = InstancePageStateRecordType.create({\n * id: 'instance_page_state:page1',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1']\n * })\n * ```\n *\n * @public\n */\nexport const InstancePageStateRecordType = createRecordType<TLInstancePageState>(\n\t'instance_page_state',\n\t{\n\t\tvalidator: instancePageStateValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tpageId: false,\n\t\t\tselectedShapeIds: false,\n\t\t\teditingShapeId:
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAMO;AAEP,sBAAkB;AAClB,0BAA4B;AAC5B,yBAAiC;AACjC,oBAAwC;AA2DjC,MAAM,6BAA+D,kBAAE;AAAA,EAC7E;AAAA,EACA,kBAAE,OAAO;AAAA,IACR,UAAU,kBAAE,QAAQ,qBAAqB;AAAA,IACzC,QAAI,iCAAmC,qBAAqB;AAAA,IAC5D,QAAQ;AAAA,IACR,kBAAkB,kBAAE,QAAQ,mCAAgB;AAAA,IAC5C,iBAAiB,kBAAE,QAAQ,mCAAgB;AAAA,IAC3C,iBAAiB,kBAAE,QAAQ,mCAAgB;AAAA,IAC3C,gBAAgB,oCAAiB,SAAS;AAAA,IAC1C,gBAAgB,oCAAiB,SAAS;AAAA,IAC1C,iBAAiB,oCAAiB,SAAS;AAAA,IAC3C,gBAAgB,oCAAiB,SAAS;AAAA,IAC1C,MAAM,kBAAE;AAAA,EACT,CAAC;AACF;AASO,MAAM,gCAA4B,iCAAmB,kCAAkC;AAAA,EAC7F,eAAe;AAAA,EACf,6BAA6B;AAAA,EAC7B,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,uBAAuB;AACxB,CAAU;AAeH,MAAM,kCAA8B,4CAA8B;AAAA,EACxE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,IACT;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,GAAG,UAAe;AACjB,iBAAS,kBAAkB;AAAA,MAC5B;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,GAAG,UAAe;AACjB,eAAO,SAAS;AAChB,eAAO,SAAS;AAAA,MACjB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,IAAI,CAAC,WAAgB;AACpB,eAAO,OAAO,CAAC;AAAA,MAChB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA;AAAA;AAAA,MAG9B,IAAI,CAAC,YAAY;AAAA,MAEjB;AAAA,MACA,MAAM,CAAC,YAAY;AAAA,MAEnB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,IAAI,CAAC,WAAgB;AACpB,eAAO,mBAAmB,OAAO;AACjC,eAAO,OAAO;AACd,eAAO,kBAAkB,OAAO;AAChC,eAAO,OAAO;AACd,eAAO,kBAAkB,OAAO;AAChC,eAAO,OAAO;AACd,eAAO,iBAAiB,OAAO;AAC/B,eAAO,OAAO;AACd,eAAO,iBAAiB,OAAO;AAC/B,eAAO,OAAO;AACd,eAAO,kBAAkB,OAAO,mBAAmB,OAAO,cAAc;AACxE,eAAO,OAAO;AACd,eAAO,iBAAiB,OAAO;AAC/B,eAAO,OAAO;AAAA,MACf;AAAA,MACA,MAAM,CAAC,WAAgB;AACtB,eAAO,cAAc,OAAO;AAC5B,eAAO,OAAO;AACd,eAAO,aAAa,OAAO;AAC3B,eAAO,OAAO;AACd,eAAO,aAAa,OAAO;AAC3B,eAAO,OAAO;AACd,eAAO,YAAY,OAAO;AAC1B,eAAO,OAAO;AACd,eAAO,YAAY,OAAO;AAC1B,eAAO,OAAO;AACd,eAAO,aAAa,OAAO;AAC3B,eAAO,OAAO;AACd,eAAO,eAAe,OAAO;AAC7B,eAAO,OAAO;AAAA,MACf;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAqBM,MAAM,kCAA8B;AAAA,EAC1C;AAAA,EACA;AAAA,IACC,WAAW;AAAA,IACX,OAAO;AAAA,IACP,eAAe;AAAA,MACd,QAAQ;AAAA,MACR,kBAAkB;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { shapeIdValidator } from '../shapes/TLBaseShape'\nimport { pageIdValidator, TLPage } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * State that is unique to a particular page within a particular browser tab.\n * This record tracks all page-specific interaction state including selected shapes,\n * editing state, hover state, and other transient UI state that is tied to\n * both a specific page and a specific browser session.\n *\n * Each combination of page and browser tab has its own TLInstancePageState record.\n *\n * @example\n * ```ts\n * const pageState: TLInstancePageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1', 'shape:circle2'],\n * hoveredShapeId: 'shape:text3',\n * editingShapeId: null,\n * focusedGroupId: null\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePageState extends BaseRecord<\n\t'instance_page_state',\n\tTLInstancePageStateId\n> {\n\tpageId: RecordId<TLPage>\n\tselectedShapeIds: TLShapeId[]\n\thintingShapeIds: TLShapeId[]\n\terasingShapeIds: TLShapeId[]\n\thoveredShapeId: TLShapeId | null\n\teditingShapeId: TLShapeId | null\n\tcroppingShapeId: TLShapeId | null\n\tfocusedGroupId: TLShapeId | null\n\tmeta: JsonObject\n}\n\n/**\n * Runtime validator for TLInstancePageState records. Validates the structure\n * and types of all instance page state properties to ensure data integrity.\n *\n * @example\n * ```ts\n * const pageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1'],\n * // ... other properties\n * }\n * const isValid = instancePageStateValidator.isValid(pageState) // true\n * ```\n *\n * @public\n */\nexport const instancePageStateValidator: T.Validator<TLInstancePageState> = T.model(\n\t'instance_page_state',\n\tT.object({\n\t\ttypeName: T.literal('instance_page_state'),\n\t\tid: idValidator<TLInstancePageStateId>('instance_page_state'),\n\t\tpageId: pageIdValidator,\n\t\tselectedShapeIds: T.arrayOf(shapeIdValidator),\n\t\thintingShapeIds: T.arrayOf(shapeIdValidator),\n\t\terasingShapeIds: T.arrayOf(shapeIdValidator),\n\t\thoveredShapeId: shapeIdValidator.nullable(),\n\t\teditingShapeId: shapeIdValidator.nullable(),\n\t\tcroppingShapeId: shapeIdValidator.nullable(),\n\t\tfocusedGroupId: shapeIdValidator.nullable(),\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n)\n\n/**\n * Migration version identifiers for TLInstancePageState records. Each version\n * represents a schema change that requires data transformation when loading\n * older documents.\n *\n * @public\n */\nexport const instancePageStateVersions = createMigrationIds('com.tldraw.instance_page_state', {\n\tAddCroppingId: 1,\n\tRemoveInstanceIdAndCameraId: 2,\n\tAddMeta: 3,\n\tRenameProperties: 4,\n\tRenamePropertiesAgain: 5,\n} as const)\n\n/**\n * Migration sequence for TLInstancePageState records. Defines how to transform\n * instance page state records between different schema versions, ensuring data\n * compatibility when loading documents created with different versions.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migrated = instancePageStateMigrations.migrate(oldState, targetVersion)\n * ```\n *\n * @public\n */\nexport const instancePageStateMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance_page_state',\n\trecordType: 'instance_page_state',\n\tsequence: [\n\t\t{\n\t\t\tid: instancePageStateVersions.AddCroppingId,\n\t\t\tup(instance: any) {\n\t\t\t\tinstance.croppingShapeId = null\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RemoveInstanceIdAndCameraId,\n\t\t\tup(instance: any) {\n\t\t\t\tdelete instance.instanceId\n\t\t\t\tdelete instance.cameraId\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.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: instancePageStateVersions.RenameProperties,\n\t\t\t// this migration is cursed: it was written wrong and doesn't do anything.\n\t\t\t// rather than replace it, I've added another migration below that fixes it.\n\t\t\tup: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RenamePropertiesAgain,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.selectedShapeIds = record.selectedIds\n\t\t\t\tdelete record.selectedIds\n\t\t\t\trecord.hintingShapeIds = record.hintingIds\n\t\t\t\tdelete record.hintingIds\n\t\t\t\trecord.erasingShapeIds = record.erasingIds\n\t\t\t\tdelete record.erasingIds\n\t\t\t\trecord.hoveredShapeId = record.hoveredId\n\t\t\t\tdelete record.hoveredId\n\t\t\t\trecord.editingShapeId = record.editingId\n\t\t\t\tdelete record.editingId\n\t\t\t\trecord.croppingShapeId = record.croppingShapeId ?? record.croppingId ?? null\n\t\t\t\tdelete record.croppingId\n\t\t\t\trecord.focusedGroupId = record.focusLayerId\n\t\t\t\tdelete record.focusLayerId\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\trecord.selectedIds = record.selectedShapeIds\n\t\t\t\tdelete record.selectedShapeIds\n\t\t\t\trecord.hintingIds = record.hintingShapeIds\n\t\t\t\tdelete record.hintingShapeIds\n\t\t\t\trecord.erasingIds = record.erasingShapeIds\n\t\t\t\tdelete record.erasingShapeIds\n\t\t\t\trecord.hoveredId = record.hoveredShapeId\n\t\t\t\tdelete record.hoveredShapeId\n\t\t\t\trecord.editingId = record.editingShapeId\n\t\t\t\tdelete record.editingShapeId\n\t\t\t\trecord.croppingId = record.croppingShapeId\n\t\t\t\tdelete record.croppingShapeId\n\t\t\t\trecord.focusLayerId = record.focusedGroupId\n\t\t\t\tdelete record.focusedGroupId\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The RecordType definition for TLInstancePageState records. Defines validation,\n * scope, and default properties for instance page state records.\n *\n * Instance page states are scoped to the session level, meaning they are\n * specific to a browser tab and don't persist across sessions or sync\n * in collaborative environments.\n *\n * @example\n * ```ts\n * const pageState = InstancePageStateRecordType.create({\n * id: 'instance_page_state:page1',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1']\n * })\n * ```\n *\n * @public\n */\nexport const InstancePageStateRecordType = createRecordType<TLInstancePageState>(\n\t'instance_page_state',\n\t{\n\t\tvalidator: instancePageStateValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tpageId: false,\n\t\t\tselectedShapeIds: false,\n\t\t\t// editingShapeId is set with `history: 'ignore'`, so entering the editing\n\t\t\t// state is never undoable. Marking it ephemeral keeps undo/redo from\n\t\t\t// reapplying a stale editingShapeId (e.g. after a shape it pointed at was\n\t\t\t// deleted), which could leave the editor pointing at a missing shape.\n\t\t\teditingShapeId: true,\n\t\t\tcroppingShapeId: false,\n\t\t\tmeta: false,\n\n\t\t\thintingShapeIds: true,\n\t\t\terasingShapeIds: true,\n\t\t\thoveredShapeId: true,\n\t\t\tfocusedGroupId: true,\n\t\t},\n\t}\n).withDefaultProperties(\n\t(): Omit<TLInstancePageState, 'id' | 'typeName' | 'pageId'> => ({\n\t\teditingShapeId: null,\n\t\tcroppingShapeId: null,\n\t\tselectedShapeIds: [],\n\t\thoveredShapeId: null,\n\t\terasingShapeIds: [],\n\t\thintingShapeIds: [],\n\t\tfocusedGroupId: null,\n\t\tmeta: {},\n\t})\n)\n\n/**\n * A unique identifier for TLInstancePageState records.\n *\n * Instance page state IDs follow the format 'instance_page_state:' followed\n * by a unique identifier, typically related to the page ID.\n *\n * @example\n * ```ts\n * const stateId: TLInstancePageStateId = 'instance_page_state:page1'\n * ```\n *\n * @public\n */\nexport type TLInstancePageStateId = RecordId<TLInstancePageState>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -30,15 +30,16 @@ var import_geometry_types = require("../misc/geometry-types");
|
|
|
30
30
|
var import_id_validator = require("../misc/id-validator");
|
|
31
31
|
var import_TLCursor = require("../misc/TLCursor");
|
|
32
32
|
var import_TLScribble = require("../misc/TLScribble");
|
|
33
|
+
var import_TLUser = require("./TLUser");
|
|
33
34
|
const instancePresenceValidator = import_validate.T.model(
|
|
34
35
|
"instance_presence",
|
|
35
36
|
import_validate.T.object({
|
|
36
37
|
typeName: import_validate.T.literal("instance_presence"),
|
|
37
38
|
id: (0, import_id_validator.idValidator)("instance_presence"),
|
|
38
|
-
userId:
|
|
39
|
+
userId: import_TLUser.userIdValidator,
|
|
39
40
|
userName: import_validate.T.string,
|
|
40
41
|
lastActivityTimestamp: import_validate.T.number.nullable(),
|
|
41
|
-
followingUserId:
|
|
42
|
+
followingUserId: import_TLUser.userIdValidator.nullable(),
|
|
42
43
|
cursor: import_validate.T.object({
|
|
43
44
|
x: import_validate.T.number,
|
|
44
45
|
y: import_validate.T.number,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/records/TLPresence.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorTypeValidator, TLCursor } from '../misc/TLCursor'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * Represents the presence state of a user in a collaborative tldraw session.\n * This record tracks what another user is doing: their cursor position, selected\n * shapes, current page, and other real-time activity indicators.\n *\n * Instance presence records are used in multiplayer environments to show\n * where other collaborators are working and what they're doing.\n *\n * @example\n * ```ts\n * const presence: TLInstancePresence = {\n * id: 'instance_presence:user123',\n * typeName: 'instance_presence',\n * userId: 'user123',\n * userName: 'Alice',\n * color: '#FF6B6B',\n * cursor: { x: 100, y: 150, type: 'default', rotation: 0 },\n * currentPageId: 'page:main',\n * selectedShapeIds: ['shape:rect1']\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {\n\tuserId:
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAMO;AAEP,sBAAkB;AAClB,4BAA4C;AAC5C,0BAA4B;AAC5B,sBAA8C;AAC9C,wBAA8C;
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorTypeValidator, TLCursor } from '../misc/TLCursor'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\nimport { TLUserId, userIdValidator } from './TLUser'\n\n/**\n * Represents the presence state of a user in a collaborative tldraw session.\n * This record tracks what another user is doing: their cursor position, selected\n * shapes, current page, and other real-time activity indicators.\n *\n * Instance presence records are used in multiplayer environments to show\n * where other collaborators are working and what they're doing.\n *\n * @example\n * ```ts\n * const presence: TLInstancePresence = {\n * id: 'instance_presence:user123',\n * typeName: 'instance_presence',\n * userId: 'user123',\n * userName: 'Alice',\n * color: '#FF6B6B',\n * cursor: { x: 100, y: 150, type: 'default', rotation: 0 },\n * currentPageId: 'page:main',\n * selectedShapeIds: ['shape:rect1']\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {\n\tuserId: TLUserId\n\tuserName: string\n\tlastActivityTimestamp: number | null\n\tcolor: string // can be any hex color\n\tcamera: { x: number; y: number; z: number } | null\n\tselectedShapeIds: TLShapeId[]\n\tcurrentPageId: TLPageId\n\tbrush: BoxModel | null\n\tscribbles: TLScribble[]\n\tscreenBounds: BoxModel | null\n\tfollowingUserId: TLUserId | null\n\tcursor: {\n\t\tx: number\n\t\ty: number\n\t\ttype: TLCursor['type']\n\t\trotation: number\n\t} | null\n\tchatMessage: string\n\tmeta: JsonObject\n}\n\n/**\n * A unique identifier for TLInstancePresence records.\n *\n * Instance presence IDs follow the format 'instance_presence:' followed\n * by a unique identifier, typically the user ID.\n *\n * @example\n * ```ts\n * const presenceId: TLInstancePresenceID = 'instance_presence:user123'\n * ```\n *\n * @public\n */\nexport type TLInstancePresenceID = RecordId<TLInstancePresence>\n\n/**\n * Runtime validator for TLInstancePresence records. Validates the structure\n * and types of all instance presence properties to ensure data integrity.\n *\n * @example\n * ```ts\n * const presence = {\n * id: 'instance_presence:user1',\n * typeName: 'instance_presence',\n * userId: 'user1',\n * userName: 'John',\n * color: '#007AFF',\n * cursor: { x: 0, y: 0, type: 'default', rotation: 0 },\n * currentPageId: 'page:main',\n * selectedShapeIds: []\n * }\n * const isValid = instancePresenceValidator.isValid(presence) // true\n * ```\n *\n * @public\n */\nexport const instancePresenceValidator: T.Validator<TLInstancePresence> = T.model(\n\t'instance_presence',\n\tT.object({\n\t\ttypeName: T.literal('instance_presence'),\n\t\tid: idValidator<TLInstancePresenceID>('instance_presence'),\n\t\tuserId: userIdValidator,\n\t\tuserName: T.string,\n\t\tlastActivityTimestamp: T.number.nullable(),\n\t\tfollowingUserId: userIdValidator.nullable(),\n\t\tcursor: T.object({\n\t\t\tx: T.number,\n\t\t\ty: T.number,\n\t\t\ttype: cursorTypeValidator,\n\t\t\trotation: T.number,\n\t\t}).nullable(),\n\t\tcolor: T.string,\n\t\tcamera: T.object({\n\t\t\tx: T.number,\n\t\t\ty: T.number,\n\t\t\tz: T.number,\n\t\t}).nullable(),\n\t\tscreenBounds: boxModelValidator.nullable(),\n\t\tselectedShapeIds: T.arrayOf(idValidator<TLShapeId>('shape')),\n\t\tcurrentPageId: idValidator<TLPageId>('page'),\n\t\tbrush: boxModelValidator.nullable(),\n\t\tscribbles: T.arrayOf(scribbleValidator),\n\t\tchatMessage: T.string,\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n)\n\n/**\n * Migration version identifiers for TLInstancePresence records. Each version\n * represents a schema change that requires data transformation when loading\n * older documents.\n *\n * @public\n */\nexport const instancePresenceVersions = createMigrationIds('com.tldraw.instance_presence', {\n\tAddScribbleDelay: 1,\n\tRemoveInstanceId: 2,\n\tAddChatMessage: 3,\n\tAddMeta: 4,\n\tRenameSelectedShapeIds: 5,\n\tNullableCameraCursor: 6,\n} as const)\n\n/**\n * Migration sequence for TLInstancePresence records. Defines how to transform\n * instance presence records between different schema versions, ensuring data\n * compatibility when loading documents created with different versions.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migrated = instancePresenceMigrations.migrate(oldPresence, targetVersion)\n * ```\n *\n * @public\n */\nexport const instancePresenceMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance_presence',\n\trecordType: 'instance_presence',\n\tsequence: [\n\t\t{\n\t\t\tid: instancePresenceVersions.AddScribbleDelay,\n\t\t\tup: (instance: any) => {\n\t\t\t\tif (instance.scribble !== null) {\n\t\t\t\t\tinstance.scribble.delay = 0\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.RemoveInstanceId,\n\t\t\tup: (instance: any) => {\n\t\t\t\tdelete instance.instanceId\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.AddChatMessage,\n\t\t\tup: (instance: any) => {\n\t\t\t\tinstance.chatMessage = ''\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.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: instancePresenceVersions.RenameSelectedShapeIds,\n\t\t\tup: (_record) => {\n\t\t\t\t// noop, whoopsie\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.NullableCameraCursor,\n\t\t\tup: (_record: any) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tif (record.camera === null) {\n\t\t\t\t\trecord.camera = { x: 0, y: 0, z: 1 }\n\t\t\t\t}\n\t\t\t\tif (record.lastActivityTimestamp === null) {\n\t\t\t\t\trecord.lastActivityTimestamp = 0\n\t\t\t\t}\n\t\t\t\tif (record.cursor === null) {\n\t\t\t\t\trecord.cursor = { type: 'default', x: 0, y: 0, rotation: 0 }\n\t\t\t\t}\n\t\t\t\tif (record.screenBounds === null) {\n\t\t\t\t\trecord.screenBounds = { x: 0, y: 0, w: 1, h: 1 }\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The RecordType definition for TLInstancePresence records. Defines validation,\n * scope, and default properties for instance presence records.\n *\n * Instance presence records are scoped to the presence level, meaning they\n * represent real-time collaborative state that is ephemeral and tied to\n * active user sessions.\n *\n * @example\n * ```ts\n * const presence = InstancePresenceRecordType.create({\n * id: 'instance_presence:user1',\n * userId: 'user1',\n * userName: 'Alice',\n * color: '#FF6B6B',\n * currentPageId: 'page:main'\n * })\n * ```\n *\n * @public\n */\nexport const InstancePresenceRecordType = createRecordType<TLInstancePresence>(\n\t'instance_presence',\n\t{\n\t\tvalidator: instancePresenceValidator,\n\t\tscope: 'presence',\n\t}\n).withDefaultProperties(() => ({\n\tlastActivityTimestamp: null,\n\tfollowingUserId: null,\n\tcolor: '#FF0000',\n\tcamera: null,\n\tcursor: null,\n\tscreenBounds: null,\n\tselectedShapeIds: [],\n\tbrush: null,\n\tscribbles: [],\n\tchatMessage: '',\n\tmeta: {},\n}))\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/index.d.mts
CHANGED
|
@@ -1924,7 +1924,7 @@ export declare function getDefaultUserPresence(store: TLStore, user: TLUser): {
|
|
|
1924
1924
|
x: number;
|
|
1925
1925
|
y: number;
|
|
1926
1926
|
};
|
|
1927
|
-
followingUserId:
|
|
1927
|
+
followingUserId: TLUserId | null;
|
|
1928
1928
|
lastActivityTimestamp: number;
|
|
1929
1929
|
meta: {};
|
|
1930
1930
|
screenBounds: BoxModel;
|
|
@@ -5101,8 +5101,8 @@ export declare interface TLInstance extends BaseRecord<'instance', TLInstanceId>
|
|
|
5101
5101
|
currentPageId: TLPageId;
|
|
5102
5102
|
opacityForNextShape: TLOpacityType;
|
|
5103
5103
|
stylesForNextShape: Record<string, unknown>;
|
|
5104
|
-
followingUserId: null |
|
|
5105
|
-
highlightedUserIds:
|
|
5104
|
+
followingUserId: null | TLUserId;
|
|
5105
|
+
highlightedUserIds: TLUserId[];
|
|
5106
5106
|
brush: BoxModel | null;
|
|
5107
5107
|
cursor: TLCursor;
|
|
5108
5108
|
scribbles: TLScribble[];
|
|
@@ -5250,7 +5250,7 @@ export declare type TLInstancePageStateId = RecordId<TLInstancePageState>;
|
|
|
5250
5250
|
* @public
|
|
5251
5251
|
*/
|
|
5252
5252
|
export declare interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {
|
|
5253
|
-
userId:
|
|
5253
|
+
userId: TLUserId;
|
|
5254
5254
|
userName: string;
|
|
5255
5255
|
lastActivityTimestamp: null | number;
|
|
5256
5256
|
color: string;
|
|
@@ -5264,7 +5264,7 @@ export declare interface TLInstancePresence extends BaseRecord<'instance_presenc
|
|
|
5264
5264
|
brush: BoxModel | null;
|
|
5265
5265
|
scribbles: TLScribble[];
|
|
5266
5266
|
screenBounds: BoxModel | null;
|
|
5267
|
-
followingUserId: null |
|
|
5267
|
+
followingUserId: null | TLUserId;
|
|
5268
5268
|
cursor: {
|
|
5269
5269
|
rotation: number;
|
|
5270
5270
|
type: TLCursor['type'];
|
package/dist-esm/index.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import { cursorValidator } from "../misc/TLCursor.mjs";
|
|
|
11
11
|
import { opacityValidator } from "../misc/TLOpacity.mjs";
|
|
12
12
|
import { scribbleValidator } from "../misc/TLScribble.mjs";
|
|
13
13
|
import { pageIdValidator } from "./TLPage.mjs";
|
|
14
|
+
import { userIdValidator } from "./TLUser.mjs";
|
|
14
15
|
const shouldKeyBePreservedBetweenSessions = {
|
|
15
16
|
// This object defines keys that should be preserved across calls to loadSnapshot()
|
|
16
17
|
id: false,
|
|
@@ -93,7 +94,7 @@ function createInstanceRecordType(stylesById) {
|
|
|
93
94
|
typeName: T.literal("instance"),
|
|
94
95
|
id: idValidator("instance"),
|
|
95
96
|
currentPageId: pageIdValidator,
|
|
96
|
-
followingUserId:
|
|
97
|
+
followingUserId: userIdValidator.nullable(),
|
|
97
98
|
brush: boxModelValidator.nullable(),
|
|
98
99
|
opacityForNextShape: opacityValidator,
|
|
99
100
|
stylesForNextShape: T.object(stylesForNextShapeValidators),
|
|
@@ -110,7 +111,7 @@ function createInstanceRecordType(stylesById) {
|
|
|
110
111
|
isGridMode: T.boolean,
|
|
111
112
|
chatMessage: T.string,
|
|
112
113
|
isChatting: T.boolean,
|
|
113
|
-
highlightedUserIds: T.arrayOf(
|
|
114
|
+
highlightedUserIds: T.arrayOf(userIdValidator),
|
|
114
115
|
isFocused: T.boolean,
|
|
115
116
|
devicePixelRatio: T.number,
|
|
116
117
|
isCoarsePointer: T.boolean,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/records/TLInstance.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { filterEntries, JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorValidator, TLCursor } from '../misc/TLCursor'\nimport { opacityValidator, TLOpacityType } from '../misc/TLOpacity'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { StyleProp } from '../styles/StyleProp'\nimport { pageIdValidator, TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * State that is particular to a single browser tab. The TLInstance record stores\n * all session-specific state including cursor position, selected tools, UI preferences,\n * and temporary interaction state.\n *\n * Each browser tab has exactly one TLInstance record that persists for the duration\n * of the session and tracks the user's current interaction state.\n *\n * @example\n * ```ts\n * const instance: TLInstance = {\n * id: 'instance:instance',\n * typeName: 'instance',\n * currentPageId: 'page:page1',\n * cursor: { type: 'default', rotation: 0 },\n * screenBounds: { x: 0, y: 0, w: 1920, h: 1080 },\n * isFocusMode: false,\n * isGridMode: true\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstance extends BaseRecord<'instance', TLInstanceId> {\n\tcurrentPageId: TLPageId\n\topacityForNextShape: TLOpacityType\n\tstylesForNextShape: Record<string, unknown>\n\tfollowingUserId: string | null\n\thighlightedUserIds: string[]\n\tbrush: BoxModel | null\n\tcursor: TLCursor\n\tscribbles: TLScribble[]\n\tisFocusMode: boolean\n\tisDebugMode: boolean\n\tisToolLocked: boolean\n\texportBackground: boolean\n\tscreenBounds: BoxModel\n\tinsets: boolean[]\n\tzoomBrush: BoxModel | null\n\tchatMessage: string\n\tisChatting: boolean\n\tisPenMode: boolean\n\tisGridMode: boolean\n\tisFocused: boolean\n\tdevicePixelRatio: number\n\t/**\n\t * This is whether the primary input mechanism includes a pointing device of limited accuracy,\n\t * such as a finger on a touchscreen.\n\t */\n\tisCoarsePointer: boolean\n\t/**\n\t * Will be null if the pointer doesn't support hovering (e.g. touch), but true or false\n\t * otherwise\n\t */\n\tisHoveringCanvas: boolean | null\n\topenMenus: string[]\n\tisChangingStyle: boolean\n\tisReadonly: boolean\n\tmeta: JsonObject\n\tduplicateProps: {\n\t\tshapeIds: TLShapeId[]\n\t\toffset: {\n\t\t\tx: number\n\t\t\ty: number\n\t\t}\n\t} | null\n\t/**\n\t * Whether the camera is currently moving or idle. Used to optimize rendering\n\t * and hit-testing during panning/zooming.\n\t */\n\tcameraState: 'idle' | 'moving'\n}\n\n/**\n * Configuration object defining which TLInstance properties should be preserved\n * when loading snapshots across browser sessions. Properties marked as `true`\n * represent user preferences that should persist, while `false` indicates\n * temporary state that should reset.\n *\n * @internal\n */\nexport const shouldKeyBePreservedBetweenSessions = {\n\t// This object defines keys that should be preserved across calls to loadSnapshot()\n\n\tid: false, // meta\n\ttypeName: false, // meta\n\n\tcurrentPageId: false, // does not preserve because who knows if the page still exists\n\topacityForNextShape: false, // does not preserve because it's a temporary state\n\tstylesForNextShape: false, // does not preserve because it's a temporary state\n\tfollowingUserId: false, // does not preserve because it's a temporary state\n\thighlightedUserIds: false, // does not preserve because it's a temporary state\n\tbrush: false, // does not preserve because it's a temporary state\n\tcursor: false, // does not preserve because it's a temporary state\n\tscribbles: false, // does not preserve because it's a temporary state\n\n\tisFocusMode: true, // preserves because it's a user preference\n\tisDebugMode: true, // preserves because it's a user preference\n\tisToolLocked: true, // preserves because it's a user preference\n\texportBackground: true, // preserves because it's a user preference\n\tscreenBounds: true, // preserves because it's capturing the user's screen state\n\tinsets: true, // preserves because it's capturing the user's screen state\n\n\tzoomBrush: false, // does not preserve because it's a temporary state\n\tchatMessage: false, // does not preserve because it's a temporary state\n\tisChatting: false, // does not preserve because it's a temporary state\n\tisPenMode: false, // does not preserve because it's a temporary state\n\n\tisGridMode: true, // preserves because it's a user preference\n\tisFocused: true, // preserves because obviously\n\tdevicePixelRatio: true, // preserves because it captures the user's screen state\n\tisCoarsePointer: true, // preserves because it captures the user's screen state\n\tisHoveringCanvas: false, // does not preserve because it's a temporary state\n\topenMenus: false, // does not preserve because it's a temporary state\n\tisChangingStyle: false, // does not preserve because it's a temporary state\n\tisReadonly: true, // preserves because it's a config option\n\tmeta: false, // does not preserve because who knows what's in there, leave it up to sdk users to save and reinstate\n\tduplicateProps: false, //\n\tcameraState: false, // does not preserve because it's a temporary state\n} as const satisfies { [K in keyof TLInstance]: boolean }\n\n/**\n * Extracts only the properties from a TLInstance that should be preserved\n * between browser sessions, filtering out temporary state.\n *\n * @param val - The TLInstance to filter, or null/undefined\n * @returns A partial TLInstance containing only preservable properties, or null\n *\n * @internal\n */\nexport function pluckPreservingValues(val?: TLInstance | null): null | Partial<TLInstance> {\n\treturn val\n\t\t? (filterEntries(val, (key) => {\n\t\t\t\treturn shouldKeyBePreservedBetweenSessions[key as keyof TLInstance]\n\t\t\t}) as Partial<TLInstance>)\n\t\t: null\n}\n\n/**\n * A unique identifier for TLInstance records.\n *\n * TLInstance IDs are always the constant 'instance:instance' since there\n * is exactly one instance record per browser tab.\n *\n * @public\n */\nexport type TLInstanceId = RecordId<TLInstance>\n\n/**\n * Validator for TLInstanceId values. Ensures the ID follows the correct\n * format for instance records.\n *\n * @example\n * ```ts\n * const isValid = instanceIdValidator.isValid('instance:instance') // true\n * const isValid2 = instanceIdValidator.isValid('invalid') // false\n * ```\n *\n * @public\n */\nexport const instanceIdValidator = idValidator<TLInstanceId>('instance')\n\n/**\n * Creates the record type definition for TLInstance records, including validation\n * and default properties. The function takes a map of available style properties\n * to configure validation for the stylesForNextShape field.\n *\n * @param stylesById - Map of style property IDs to their corresponding StyleProp definitions\n * @returns A configured RecordType for TLInstance records\n *\n * @example\n * ```ts\n * const stylesMap = new Map([['color', DefaultColorStyle]])\n * const InstanceRecordType = createInstanceRecordType(stylesMap)\n *\n * const instance = InstanceRecordType.create({\n * id: 'instance:instance',\n * currentPageId: 'page:page1'\n * })\n * ```\n *\n * @public\n */\nexport function createInstanceRecordType(stylesById: Map<string, StyleProp<unknown>>) {\n\tconst stylesForNextShapeValidators = {} as Record<string, T.Validator<unknown>>\n\tfor (const [id, style] of stylesById) {\n\t\tstylesForNextShapeValidators[id] = T.optional(style)\n\t}\n\n\tconst instanceTypeValidator: T.Validator<TLInstance> = T.model(\n\t\t'instance',\n\t\tT.object({\n\t\t\ttypeName: T.literal('instance'),\n\t\t\tid: idValidator<TLInstanceId>('instance'),\n\t\t\tcurrentPageId: pageIdValidator,\n\t\t\tfollowingUserId: T.string.nullable(),\n\t\t\tbrush: boxModelValidator.nullable(),\n\t\t\topacityForNextShape: opacityValidator,\n\t\t\tstylesForNextShape: T.object(stylesForNextShapeValidators),\n\t\t\tcursor: cursorValidator,\n\t\t\tscribbles: T.arrayOf(scribbleValidator),\n\t\t\tisFocusMode: T.boolean,\n\t\t\tisDebugMode: T.boolean,\n\t\t\tisToolLocked: T.boolean,\n\t\t\texportBackground: T.boolean,\n\t\t\tscreenBounds: boxModelValidator,\n\t\t\tinsets: T.arrayOf(T.boolean),\n\t\t\tzoomBrush: boxModelValidator.nullable(),\n\t\t\tisPenMode: T.boolean,\n\t\t\tisGridMode: T.boolean,\n\t\t\tchatMessage: T.string,\n\t\t\tisChatting: T.boolean,\n\t\t\thighlightedUserIds: T.arrayOf(T.string),\n\t\t\tisFocused: T.boolean,\n\t\t\tdevicePixelRatio: T.number,\n\t\t\tisCoarsePointer: T.boolean,\n\t\t\tisHoveringCanvas: T.boolean.nullable(),\n\t\t\topenMenus: T.arrayOf(T.string),\n\t\t\tisChangingStyle: T.boolean,\n\t\t\tisReadonly: T.boolean,\n\t\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t\t\tduplicateProps: T.object({\n\t\t\t\tshapeIds: T.arrayOf(idValidator<TLShapeId>('shape')),\n\t\t\t\toffset: T.object({\n\t\t\t\t\tx: T.number,\n\t\t\t\t\ty: T.number,\n\t\t\t\t}),\n\t\t\t}).nullable(),\n\t\t\tcameraState: T.literalEnum('idle', 'moving'),\n\t\t})\n\t)\n\n\treturn createRecordType<TLInstance>('instance', {\n\t\tvalidator: instanceTypeValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tcurrentPageId: false,\n\t\t\tmeta: false,\n\n\t\t\tfollowingUserId: true,\n\t\t\topacityForNextShape: true,\n\t\t\tstylesForNextShape: true,\n\t\t\tbrush: true,\n\t\t\tcursor: true,\n\t\t\tscribbles: true,\n\t\t\tisFocusMode: true,\n\t\t\tisDebugMode: true,\n\t\t\tisToolLocked: true,\n\t\t\texportBackground: true,\n\t\t\tscreenBounds: true,\n\t\t\tinsets: true,\n\t\t\tzoomBrush: true,\n\t\t\tisPenMode: true,\n\t\t\tisGridMode: true,\n\t\t\tchatMessage: true,\n\t\t\tisChatting: true,\n\t\t\thighlightedUserIds: true,\n\t\t\tisFocused: true,\n\t\t\tdevicePixelRatio: true,\n\t\t\tisCoarsePointer: true,\n\t\t\tisHoveringCanvas: true,\n\t\t\topenMenus: true,\n\t\t\tisChangingStyle: true,\n\t\t\tisReadonly: true,\n\t\t\tduplicateProps: true,\n\t\t\tcameraState: true,\n\t\t},\n\t}).withDefaultProperties(\n\t\t(): Omit<TLInstance, 'typeName' | 'id' | 'currentPageId'> => ({\n\t\t\tfollowingUserId: null,\n\t\t\topacityForNextShape: 1,\n\t\t\tstylesForNextShape: {},\n\t\t\tbrush: null,\n\t\t\tscribbles: [],\n\t\t\tcursor: {\n\t\t\t\ttype: 'default',\n\t\t\t\trotation: 0,\n\t\t\t},\n\t\t\tisFocusMode: false,\n\t\t\texportBackground: false,\n\t\t\tisDebugMode: false,\n\t\t\tisToolLocked: false,\n\t\t\tscreenBounds: { x: 0, y: 0, w: 1080, h: 720 },\n\t\t\tinsets: [false, false, false, false],\n\t\t\tzoomBrush: null,\n\t\t\tisGridMode: false,\n\t\t\tisPenMode: false,\n\t\t\tchatMessage: '',\n\t\t\tisChatting: false,\n\t\t\thighlightedUserIds: [],\n\t\t\tisFocused: false,\n\t\t\tdevicePixelRatio: typeof window === 'undefined' ? 1 : window.devicePixelRatio,\n\t\t\tisCoarsePointer: false,\n\t\t\tisHoveringCanvas: null,\n\t\t\topenMenus: [] as string[],\n\t\t\tisChangingStyle: false,\n\t\t\tisReadonly: false,\n\t\t\tmeta: {},\n\t\t\tduplicateProps: null,\n\t\t\tcameraState: 'idle',\n\t\t})\n\t)\n}\n\n/**\n * Migration version identifiers for TLInstance records. Each version represents\n * a schema change that requires data transformation when loading older documents.\n *\n * The versions track the evolution of the instance record structure over time,\n * enabling backward and forward compatibility.\n *\n * @public\n */\nexport const instanceVersions = createMigrationIds('com.tldraw.instance', {\n\tAddTransparentExportBgs: 1,\n\tRemoveDialog: 2,\n\tAddToolLockMode: 3,\n\tRemoveExtraPropsForNextShape: 4,\n\tAddLabelColor: 5,\n\tAddFollowingUserId: 6,\n\tRemoveAlignJustify: 7,\n\tAddZoom: 8,\n\tAddVerticalAlign: 9,\n\tAddScribbleDelay: 10,\n\tRemoveUserId: 11,\n\tAddIsPenModeAndIsGridMode: 12,\n\tHoistOpacity: 13,\n\tAddChat: 14,\n\tAddHighlightedUserIds: 15,\n\tReplacePropsForNextShapeWithStylesForNextShape: 16,\n\tAddMeta: 17,\n\tRemoveCursorColor: 18,\n\tAddLonelyProperties: 19,\n\tReadOnlyReadonly: 20,\n\tAddHoveringCanvas: 21,\n\tAddScribbles: 22,\n\tAddInset: 23,\n\tAddDuplicateProps: 24,\n\tRemoveCanMoveCamera: 25,\n\tAddCameraState: 26,\n} as const)\n\n// TODO: rewrite these to use mutation\n\n/**\n * Migration sequence for TLInstance records. Defines how to transform instance\n * records between different schema versions, ensuring data compatibility when\n * loading documents created with different versions of tldraw.\n *\n * Each migration includes an 'up' function to migrate forward and optionally\n * a 'down' function for reverse migration.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migratedInstance = instanceMigrations.migrate(oldInstance, targetVersion)\n * ```\n *\n * @public\n */\nexport const instanceMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance',\n\trecordType: 'instance',\n\tsequence: [\n\t\t{\n\t\t\tid: instanceVersions.AddTransparentExportBgs,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, exportBackground: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveDialog,\n\t\t\tup: ({ dialog: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\n\t\t{\n\t\t\tid: instanceVersions.AddToolLockMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isToolLocked: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveExtraPropsForNextShape,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: Object.fromEntries(\n\t\t\t\t\t\tObject.entries(propsForNextShape).filter(([key]) =>\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'color',\n\t\t\t\t\t\t\t\t'labelColor',\n\t\t\t\t\t\t\t\t'dash',\n\t\t\t\t\t\t\t\t'fill',\n\t\t\t\t\t\t\t\t'size',\n\t\t\t\t\t\t\t\t'font',\n\t\t\t\t\t\t\t\t'align',\n\t\t\t\t\t\t\t\t'verticalAlign',\n\t\t\t\t\t\t\t\t'icon',\n\t\t\t\t\t\t\t\t'geo',\n\t\t\t\t\t\t\t\t'arrowheadStart',\n\t\t\t\t\t\t\t\t'arrowheadEnd',\n\t\t\t\t\t\t\t\t'spline',\n\t\t\t\t\t\t\t].includes(key)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLabelColor,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...propsForNextShape,\n\t\t\t\t\t\tlabelColor: 'black',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddFollowingUserId,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, followingUserId: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveAlignJustify,\n\t\t\tup: (instance: any) => {\n\t\t\t\tlet newAlign = instance.propsForNextShape.align\n\t\t\t\tif (newAlign === 'justify') {\n\t\t\t\t\tnewAlign = 'start'\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\talign: newAlign,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddZoom,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, zoomBrush: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddVerticalAlign,\n\t\t\tup: (instance: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\tverticalAlign: 'middle',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbleDelay,\n\t\t\tup: (instance: any) => {\n\t\t\t\tif (instance.scribble !== null) {\n\t\t\t\t\treturn { ...instance, scribble: { ...instance.scribble, delay: 0 } }\n\t\t\t\t}\n\t\t\t\treturn { ...instance }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveUserId,\n\t\t\tup: ({ userId: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddIsPenModeAndIsGridMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isPenMode: false, isGridMode: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.HoistOpacity,\n\t\t\tup: ({ propsForNextShape: { opacity, ...propsForNextShape }, ...instance }: any) => {\n\t\t\t\treturn { ...instance, opacityForNextShape: Number(opacity ?? '1'), propsForNextShape }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddChat,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, chatMessage: '', isChatting: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHighlightedUserIds,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, highlightedUserIds: [] }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReplacePropsForNextShapeWithStylesForNextShape,\n\t\t\tup: ({ propsForNextShape: _, ...instance }: any) => {\n\t\t\t\treturn { ...instance, stylesForNextShape: {} }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddMeta,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tmeta: {},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCursorColor,\n\t\t\tup: (record: any) => {\n\t\t\t\tconst { color: _, ...cursor } = record.cursor\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcursor,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLonelyProperties,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcanMoveCamera: true,\n\t\t\t\t\tisFocused: false,\n\t\t\t\t\tdevicePixelRatio: 1,\n\t\t\t\t\tisCoarsePointer: false,\n\t\t\t\t\topenMenus: [],\n\t\t\t\t\tisChangingStyle: false,\n\t\t\t\t\tisReadOnly: false,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReadOnlyReadonly,\n\t\t\tup: ({ isReadOnly: _isReadOnly, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisReadonly: _isReadOnly,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHoveringCanvas,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisHoveringCanvas: null,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbles,\n\t\t\tup: ({ scribble: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tscribbles: [],\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddInset,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tinsets: [false, false, false, false],\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ insets: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddDuplicateProps,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tduplicateProps: null,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ duplicateProps: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCanMoveCamera,\n\t\t\tup: ({ canMoveCamera: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (instance) => {\n\t\t\t\treturn { ...instance, canMoveCamera: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddCameraState,\n\t\t\tup: (record) => {\n\t\t\t\treturn { ...record, cameraState: 'idle' }\n\t\t\t},\n\t\t\tdown: ({ cameraState: _, ...record }: any) => {\n\t\t\t\treturn record\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The constant ID used for the singleton TLInstance record.\n *\n * Since each browser tab has exactly one instance, this constant ID\n * is used universally across the application.\n *\n * @example\n * ```ts\n * const instance = store.get(TLINSTANCE_ID)\n * if (instance) {\n * console.log('Current page:', instance.currentPageId)\n * }\n * ```\n *\n * @public\n */\nexport const TLINSTANCE_ID = 'instance:instance' as TLInstanceId\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEC;AAAA,EACA;AAAA,EACA;AAAA,OAEM;AACP,SAAS,qBAAiC;AAC1C,SAAS,SAAS;AAClB,SAAmB,yBAAyB;AAC5C,SAAS,mBAAmB;AAC5B,SAAS,uBAAiC;AAC1C,SAAS,wBAAuC;AAChD,SAAS,yBAAqC;AAE9C,SAAS,uBAAiC;
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { filterEntries, JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorValidator, TLCursor } from '../misc/TLCursor'\nimport { opacityValidator, TLOpacityType } from '../misc/TLOpacity'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { StyleProp } from '../styles/StyleProp'\nimport { pageIdValidator, TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\nimport { TLUserId, userIdValidator } from './TLUser'\n\n/**\n * State that is particular to a single browser tab. The TLInstance record stores\n * all session-specific state including cursor position, selected tools, UI preferences,\n * and temporary interaction state.\n *\n * Each browser tab has exactly one TLInstance record that persists for the duration\n * of the session and tracks the user's current interaction state.\n *\n * @example\n * ```ts\n * const instance: TLInstance = {\n * id: 'instance:instance',\n * typeName: 'instance',\n * currentPageId: 'page:page1',\n * cursor: { type: 'default', rotation: 0 },\n * screenBounds: { x: 0, y: 0, w: 1920, h: 1080 },\n * isFocusMode: false,\n * isGridMode: true\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstance extends BaseRecord<'instance', TLInstanceId> {\n\tcurrentPageId: TLPageId\n\topacityForNextShape: TLOpacityType\n\tstylesForNextShape: Record<string, unknown>\n\tfollowingUserId: TLUserId | null\n\thighlightedUserIds: TLUserId[]\n\tbrush: BoxModel | null\n\tcursor: TLCursor\n\tscribbles: TLScribble[]\n\tisFocusMode: boolean\n\tisDebugMode: boolean\n\tisToolLocked: boolean\n\texportBackground: boolean\n\tscreenBounds: BoxModel\n\tinsets: boolean[]\n\tzoomBrush: BoxModel | null\n\tchatMessage: string\n\tisChatting: boolean\n\tisPenMode: boolean\n\tisGridMode: boolean\n\tisFocused: boolean\n\tdevicePixelRatio: number\n\t/**\n\t * This is whether the primary input mechanism includes a pointing device of limited accuracy,\n\t * such as a finger on a touchscreen.\n\t */\n\tisCoarsePointer: boolean\n\t/**\n\t * Will be null if the pointer doesn't support hovering (e.g. touch), but true or false\n\t * otherwise\n\t */\n\tisHoveringCanvas: boolean | null\n\topenMenus: string[]\n\tisChangingStyle: boolean\n\tisReadonly: boolean\n\tmeta: JsonObject\n\tduplicateProps: {\n\t\tshapeIds: TLShapeId[]\n\t\toffset: {\n\t\t\tx: number\n\t\t\ty: number\n\t\t}\n\t} | null\n\t/**\n\t * Whether the camera is currently moving or idle. Used to optimize rendering\n\t * and hit-testing during panning/zooming.\n\t */\n\tcameraState: 'idle' | 'moving'\n}\n\n/**\n * Configuration object defining which TLInstance properties should be preserved\n * when loading snapshots across browser sessions. Properties marked as `true`\n * represent user preferences that should persist, while `false` indicates\n * temporary state that should reset.\n *\n * @internal\n */\nexport const shouldKeyBePreservedBetweenSessions = {\n\t// This object defines keys that should be preserved across calls to loadSnapshot()\n\n\tid: false, // meta\n\ttypeName: false, // meta\n\n\tcurrentPageId: false, // does not preserve because who knows if the page still exists\n\topacityForNextShape: false, // does not preserve because it's a temporary state\n\tstylesForNextShape: false, // does not preserve because it's a temporary state\n\tfollowingUserId: false, // does not preserve because it's a temporary state\n\thighlightedUserIds: false, // does not preserve because it's a temporary state\n\tbrush: false, // does not preserve because it's a temporary state\n\tcursor: false, // does not preserve because it's a temporary state\n\tscribbles: false, // does not preserve because it's a temporary state\n\n\tisFocusMode: true, // preserves because it's a user preference\n\tisDebugMode: true, // preserves because it's a user preference\n\tisToolLocked: true, // preserves because it's a user preference\n\texportBackground: true, // preserves because it's a user preference\n\tscreenBounds: true, // preserves because it's capturing the user's screen state\n\tinsets: true, // preserves because it's capturing the user's screen state\n\n\tzoomBrush: false, // does not preserve because it's a temporary state\n\tchatMessage: false, // does not preserve because it's a temporary state\n\tisChatting: false, // does not preserve because it's a temporary state\n\tisPenMode: false, // does not preserve because it's a temporary state\n\n\tisGridMode: true, // preserves because it's a user preference\n\tisFocused: true, // preserves because obviously\n\tdevicePixelRatio: true, // preserves because it captures the user's screen state\n\tisCoarsePointer: true, // preserves because it captures the user's screen state\n\tisHoveringCanvas: false, // does not preserve because it's a temporary state\n\topenMenus: false, // does not preserve because it's a temporary state\n\tisChangingStyle: false, // does not preserve because it's a temporary state\n\tisReadonly: true, // preserves because it's a config option\n\tmeta: false, // does not preserve because who knows what's in there, leave it up to sdk users to save and reinstate\n\tduplicateProps: false, //\n\tcameraState: false, // does not preserve because it's a temporary state\n} as const satisfies { [K in keyof TLInstance]: boolean }\n\n/**\n * Extracts only the properties from a TLInstance that should be preserved\n * between browser sessions, filtering out temporary state.\n *\n * @param val - The TLInstance to filter, or null/undefined\n * @returns A partial TLInstance containing only preservable properties, or null\n *\n * @internal\n */\nexport function pluckPreservingValues(val?: TLInstance | null): null | Partial<TLInstance> {\n\treturn val\n\t\t? (filterEntries(val, (key) => {\n\t\t\t\treturn shouldKeyBePreservedBetweenSessions[key as keyof TLInstance]\n\t\t\t}) as Partial<TLInstance>)\n\t\t: null\n}\n\n/**\n * A unique identifier for TLInstance records.\n *\n * TLInstance IDs are always the constant 'instance:instance' since there\n * is exactly one instance record per browser tab.\n *\n * @public\n */\nexport type TLInstanceId = RecordId<TLInstance>\n\n/**\n * Validator for TLInstanceId values. Ensures the ID follows the correct\n * format for instance records.\n *\n * @example\n * ```ts\n * const isValid = instanceIdValidator.isValid('instance:instance') // true\n * const isValid2 = instanceIdValidator.isValid('invalid') // false\n * ```\n *\n * @public\n */\nexport const instanceIdValidator = idValidator<TLInstanceId>('instance')\n\n/**\n * Creates the record type definition for TLInstance records, including validation\n * and default properties. The function takes a map of available style properties\n * to configure validation for the stylesForNextShape field.\n *\n * @param stylesById - Map of style property IDs to their corresponding StyleProp definitions\n * @returns A configured RecordType for TLInstance records\n *\n * @example\n * ```ts\n * const stylesMap = new Map([['color', DefaultColorStyle]])\n * const InstanceRecordType = createInstanceRecordType(stylesMap)\n *\n * const instance = InstanceRecordType.create({\n * id: 'instance:instance',\n * currentPageId: 'page:page1'\n * })\n * ```\n *\n * @public\n */\nexport function createInstanceRecordType(stylesById: Map<string, StyleProp<unknown>>) {\n\tconst stylesForNextShapeValidators = {} as Record<string, T.Validator<unknown>>\n\tfor (const [id, style] of stylesById) {\n\t\tstylesForNextShapeValidators[id] = T.optional(style)\n\t}\n\n\tconst instanceTypeValidator: T.Validator<TLInstance> = T.model(\n\t\t'instance',\n\t\tT.object({\n\t\t\ttypeName: T.literal('instance'),\n\t\t\tid: idValidator<TLInstanceId>('instance'),\n\t\t\tcurrentPageId: pageIdValidator,\n\t\t\tfollowingUserId: userIdValidator.nullable(),\n\t\t\tbrush: boxModelValidator.nullable(),\n\t\t\topacityForNextShape: opacityValidator,\n\t\t\tstylesForNextShape: T.object(stylesForNextShapeValidators),\n\t\t\tcursor: cursorValidator,\n\t\t\tscribbles: T.arrayOf(scribbleValidator),\n\t\t\tisFocusMode: T.boolean,\n\t\t\tisDebugMode: T.boolean,\n\t\t\tisToolLocked: T.boolean,\n\t\t\texportBackground: T.boolean,\n\t\t\tscreenBounds: boxModelValidator,\n\t\t\tinsets: T.arrayOf(T.boolean),\n\t\t\tzoomBrush: boxModelValidator.nullable(),\n\t\t\tisPenMode: T.boolean,\n\t\t\tisGridMode: T.boolean,\n\t\t\tchatMessage: T.string,\n\t\t\tisChatting: T.boolean,\n\t\t\thighlightedUserIds: T.arrayOf(userIdValidator),\n\t\t\tisFocused: T.boolean,\n\t\t\tdevicePixelRatio: T.number,\n\t\t\tisCoarsePointer: T.boolean,\n\t\t\tisHoveringCanvas: T.boolean.nullable(),\n\t\t\topenMenus: T.arrayOf(T.string),\n\t\t\tisChangingStyle: T.boolean,\n\t\t\tisReadonly: T.boolean,\n\t\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t\t\tduplicateProps: T.object({\n\t\t\t\tshapeIds: T.arrayOf(idValidator<TLShapeId>('shape')),\n\t\t\t\toffset: T.object({\n\t\t\t\t\tx: T.number,\n\t\t\t\t\ty: T.number,\n\t\t\t\t}),\n\t\t\t}).nullable(),\n\t\t\tcameraState: T.literalEnum('idle', 'moving'),\n\t\t})\n\t)\n\n\treturn createRecordType<TLInstance>('instance', {\n\t\tvalidator: instanceTypeValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tcurrentPageId: false,\n\t\t\tmeta: false,\n\n\t\t\tfollowingUserId: true,\n\t\t\topacityForNextShape: true,\n\t\t\tstylesForNextShape: true,\n\t\t\tbrush: true,\n\t\t\tcursor: true,\n\t\t\tscribbles: true,\n\t\t\tisFocusMode: true,\n\t\t\tisDebugMode: true,\n\t\t\tisToolLocked: true,\n\t\t\texportBackground: true,\n\t\t\tscreenBounds: true,\n\t\t\tinsets: true,\n\t\t\tzoomBrush: true,\n\t\t\tisPenMode: true,\n\t\t\tisGridMode: true,\n\t\t\tchatMessage: true,\n\t\t\tisChatting: true,\n\t\t\thighlightedUserIds: true,\n\t\t\tisFocused: true,\n\t\t\tdevicePixelRatio: true,\n\t\t\tisCoarsePointer: true,\n\t\t\tisHoveringCanvas: true,\n\t\t\topenMenus: true,\n\t\t\tisChangingStyle: true,\n\t\t\tisReadonly: true,\n\t\t\tduplicateProps: true,\n\t\t\tcameraState: true,\n\t\t},\n\t}).withDefaultProperties(\n\t\t(): Omit<TLInstance, 'typeName' | 'id' | 'currentPageId'> => ({\n\t\t\tfollowingUserId: null,\n\t\t\topacityForNextShape: 1,\n\t\t\tstylesForNextShape: {},\n\t\t\tbrush: null,\n\t\t\tscribbles: [],\n\t\t\tcursor: {\n\t\t\t\ttype: 'default',\n\t\t\t\trotation: 0,\n\t\t\t},\n\t\t\tisFocusMode: false,\n\t\t\texportBackground: false,\n\t\t\tisDebugMode: false,\n\t\t\tisToolLocked: false,\n\t\t\tscreenBounds: { x: 0, y: 0, w: 1080, h: 720 },\n\t\t\tinsets: [false, false, false, false],\n\t\t\tzoomBrush: null,\n\t\t\tisGridMode: false,\n\t\t\tisPenMode: false,\n\t\t\tchatMessage: '',\n\t\t\tisChatting: false,\n\t\t\thighlightedUserIds: [],\n\t\t\tisFocused: false,\n\t\t\tdevicePixelRatio: typeof window === 'undefined' ? 1 : window.devicePixelRatio,\n\t\t\tisCoarsePointer: false,\n\t\t\tisHoveringCanvas: null,\n\t\t\topenMenus: [] as string[],\n\t\t\tisChangingStyle: false,\n\t\t\tisReadonly: false,\n\t\t\tmeta: {},\n\t\t\tduplicateProps: null,\n\t\t\tcameraState: 'idle',\n\t\t})\n\t)\n}\n\n/**\n * Migration version identifiers for TLInstance records. Each version represents\n * a schema change that requires data transformation when loading older documents.\n *\n * The versions track the evolution of the instance record structure over time,\n * enabling backward and forward compatibility.\n *\n * @public\n */\nexport const instanceVersions = createMigrationIds('com.tldraw.instance', {\n\tAddTransparentExportBgs: 1,\n\tRemoveDialog: 2,\n\tAddToolLockMode: 3,\n\tRemoveExtraPropsForNextShape: 4,\n\tAddLabelColor: 5,\n\tAddFollowingUserId: 6,\n\tRemoveAlignJustify: 7,\n\tAddZoom: 8,\n\tAddVerticalAlign: 9,\n\tAddScribbleDelay: 10,\n\tRemoveUserId: 11,\n\tAddIsPenModeAndIsGridMode: 12,\n\tHoistOpacity: 13,\n\tAddChat: 14,\n\tAddHighlightedUserIds: 15,\n\tReplacePropsForNextShapeWithStylesForNextShape: 16,\n\tAddMeta: 17,\n\tRemoveCursorColor: 18,\n\tAddLonelyProperties: 19,\n\tReadOnlyReadonly: 20,\n\tAddHoveringCanvas: 21,\n\tAddScribbles: 22,\n\tAddInset: 23,\n\tAddDuplicateProps: 24,\n\tRemoveCanMoveCamera: 25,\n\tAddCameraState: 26,\n} as const)\n\n// TODO: rewrite these to use mutation\n\n/**\n * Migration sequence for TLInstance records. Defines how to transform instance\n * records between different schema versions, ensuring data compatibility when\n * loading documents created with different versions of tldraw.\n *\n * Each migration includes an 'up' function to migrate forward and optionally\n * a 'down' function for reverse migration.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migratedInstance = instanceMigrations.migrate(oldInstance, targetVersion)\n * ```\n *\n * @public\n */\nexport const instanceMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance',\n\trecordType: 'instance',\n\tsequence: [\n\t\t{\n\t\t\tid: instanceVersions.AddTransparentExportBgs,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, exportBackground: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveDialog,\n\t\t\tup: ({ dialog: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\n\t\t{\n\t\t\tid: instanceVersions.AddToolLockMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isToolLocked: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveExtraPropsForNextShape,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: Object.fromEntries(\n\t\t\t\t\t\tObject.entries(propsForNextShape).filter(([key]) =>\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'color',\n\t\t\t\t\t\t\t\t'labelColor',\n\t\t\t\t\t\t\t\t'dash',\n\t\t\t\t\t\t\t\t'fill',\n\t\t\t\t\t\t\t\t'size',\n\t\t\t\t\t\t\t\t'font',\n\t\t\t\t\t\t\t\t'align',\n\t\t\t\t\t\t\t\t'verticalAlign',\n\t\t\t\t\t\t\t\t'icon',\n\t\t\t\t\t\t\t\t'geo',\n\t\t\t\t\t\t\t\t'arrowheadStart',\n\t\t\t\t\t\t\t\t'arrowheadEnd',\n\t\t\t\t\t\t\t\t'spline',\n\t\t\t\t\t\t\t].includes(key)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLabelColor,\n\t\t\tup: ({ propsForNextShape, ...instance }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...propsForNextShape,\n\t\t\t\t\t\tlabelColor: 'black',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddFollowingUserId,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, followingUserId: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveAlignJustify,\n\t\t\tup: (instance: any) => {\n\t\t\t\tlet newAlign = instance.propsForNextShape.align\n\t\t\t\tif (newAlign === 'justify') {\n\t\t\t\t\tnewAlign = 'start'\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\talign: newAlign,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddZoom,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, zoomBrush: null }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddVerticalAlign,\n\t\t\tup: (instance: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...instance,\n\t\t\t\t\tpropsForNextShape: {\n\t\t\t\t\t\t...instance.propsForNextShape,\n\t\t\t\t\t\tverticalAlign: 'middle',\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbleDelay,\n\t\t\tup: (instance: any) => {\n\t\t\t\tif (instance.scribble !== null) {\n\t\t\t\t\treturn { ...instance, scribble: { ...instance.scribble, delay: 0 } }\n\t\t\t\t}\n\t\t\t\treturn { ...instance }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveUserId,\n\t\t\tup: ({ userId: _, ...instance }: any) => {\n\t\t\t\treturn instance\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddIsPenModeAndIsGridMode,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, isPenMode: false, isGridMode: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.HoistOpacity,\n\t\t\tup: ({ propsForNextShape: { opacity, ...propsForNextShape }, ...instance }: any) => {\n\t\t\t\treturn { ...instance, opacityForNextShape: Number(opacity ?? '1'), propsForNextShape }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddChat,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, chatMessage: '', isChatting: false }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHighlightedUserIds,\n\t\t\tup: (instance) => {\n\t\t\t\treturn { ...instance, highlightedUserIds: [] }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReplacePropsForNextShapeWithStylesForNextShape,\n\t\t\tup: ({ propsForNextShape: _, ...instance }: any) => {\n\t\t\t\treturn { ...instance, stylesForNextShape: {} }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddMeta,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tmeta: {},\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCursorColor,\n\t\t\tup: (record: any) => {\n\t\t\t\tconst { color: _, ...cursor } = record.cursor\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcursor,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddLonelyProperties,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tcanMoveCamera: true,\n\t\t\t\t\tisFocused: false,\n\t\t\t\t\tdevicePixelRatio: 1,\n\t\t\t\t\tisCoarsePointer: false,\n\t\t\t\t\topenMenus: [],\n\t\t\t\t\tisChangingStyle: false,\n\t\t\t\t\tisReadOnly: false,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.ReadOnlyReadonly,\n\t\t\tup: ({ isReadOnly: _isReadOnly, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisReadonly: _isReadOnly,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddHoveringCanvas,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tisHoveringCanvas: null,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddScribbles,\n\t\t\tup: ({ scribble: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tscribbles: [],\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddInset,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tinsets: [false, false, false, false],\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ insets: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddDuplicateProps,\n\t\t\tup: (record) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t\tduplicateProps: null,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: ({ duplicateProps: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.RemoveCanMoveCamera,\n\t\t\tup: ({ canMoveCamera: _, ...record }: any) => {\n\t\t\t\treturn {\n\t\t\t\t\t...record,\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (instance) => {\n\t\t\t\treturn { ...instance, canMoveCamera: true }\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instanceVersions.AddCameraState,\n\t\t\tup: (record) => {\n\t\t\t\treturn { ...record, cameraState: 'idle' }\n\t\t\t},\n\t\t\tdown: ({ cameraState: _, ...record }: any) => {\n\t\t\t\treturn record\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The constant ID used for the singleton TLInstance record.\n *\n * Since each browser tab has exactly one instance, this constant ID\n * is used universally across the application.\n *\n * @example\n * ```ts\n * const instance = store.get(TLINSTANCE_ID)\n * if (instance) {\n * console.log('Current page:', instance.currentPageId)\n * }\n * ```\n *\n * @public\n */\nexport const TLINSTANCE_ID = 'instance:instance' as TLInstanceId\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -107,7 +107,11 @@ const InstancePageStateRecordType = createRecordType(
|
|
|
107
107
|
ephemeralKeys: {
|
|
108
108
|
pageId: false,
|
|
109
109
|
selectedShapeIds: false,
|
|
110
|
-
editingShapeId:
|
|
110
|
+
// editingShapeId is set with `history: 'ignore'`, so entering the editing
|
|
111
|
+
// state is never undoable. Marking it ephemeral keeps undo/redo from
|
|
112
|
+
// reapplying a stale editingShapeId (e.g. after a shape it pointed at was
|
|
113
|
+
// deleted), which could leave the editor pointing at a missing shape.
|
|
114
|
+
editingShapeId: true,
|
|
111
115
|
croppingShapeId: false,
|
|
112
116
|
meta: false,
|
|
113
117
|
hintingShapeIds: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/records/TLPageState.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { shapeIdValidator } from '../shapes/TLBaseShape'\nimport { pageIdValidator, TLPage } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * State that is unique to a particular page within a particular browser tab.\n * This record tracks all page-specific interaction state including selected shapes,\n * editing state, hover state, and other transient UI state that is tied to\n * both a specific page and a specific browser session.\n *\n * Each combination of page and browser tab has its own TLInstancePageState record.\n *\n * @example\n * ```ts\n * const pageState: TLInstancePageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1', 'shape:circle2'],\n * hoveredShapeId: 'shape:text3',\n * editingShapeId: null,\n * focusedGroupId: null\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePageState extends BaseRecord<\n\t'instance_page_state',\n\tTLInstancePageStateId\n> {\n\tpageId: RecordId<TLPage>\n\tselectedShapeIds: TLShapeId[]\n\thintingShapeIds: TLShapeId[]\n\terasingShapeIds: TLShapeId[]\n\thoveredShapeId: TLShapeId | null\n\teditingShapeId: TLShapeId | null\n\tcroppingShapeId: TLShapeId | null\n\tfocusedGroupId: TLShapeId | null\n\tmeta: JsonObject\n}\n\n/**\n * Runtime validator for TLInstancePageState records. Validates the structure\n * and types of all instance page state properties to ensure data integrity.\n *\n * @example\n * ```ts\n * const pageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1'],\n * // ... other properties\n * }\n * const isValid = instancePageStateValidator.isValid(pageState) // true\n * ```\n *\n * @public\n */\nexport const instancePageStateValidator: T.Validator<TLInstancePageState> = T.model(\n\t'instance_page_state',\n\tT.object({\n\t\ttypeName: T.literal('instance_page_state'),\n\t\tid: idValidator<TLInstancePageStateId>('instance_page_state'),\n\t\tpageId: pageIdValidator,\n\t\tselectedShapeIds: T.arrayOf(shapeIdValidator),\n\t\thintingShapeIds: T.arrayOf(shapeIdValidator),\n\t\terasingShapeIds: T.arrayOf(shapeIdValidator),\n\t\thoveredShapeId: shapeIdValidator.nullable(),\n\t\teditingShapeId: shapeIdValidator.nullable(),\n\t\tcroppingShapeId: shapeIdValidator.nullable(),\n\t\tfocusedGroupId: shapeIdValidator.nullable(),\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n)\n\n/**\n * Migration version identifiers for TLInstancePageState records. Each version\n * represents a schema change that requires data transformation when loading\n * older documents.\n *\n * @public\n */\nexport const instancePageStateVersions = createMigrationIds('com.tldraw.instance_page_state', {\n\tAddCroppingId: 1,\n\tRemoveInstanceIdAndCameraId: 2,\n\tAddMeta: 3,\n\tRenameProperties: 4,\n\tRenamePropertiesAgain: 5,\n} as const)\n\n/**\n * Migration sequence for TLInstancePageState records. Defines how to transform\n * instance page state records between different schema versions, ensuring data\n * compatibility when loading documents created with different versions.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migrated = instancePageStateMigrations.migrate(oldState, targetVersion)\n * ```\n *\n * @public\n */\nexport const instancePageStateMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance_page_state',\n\trecordType: 'instance_page_state',\n\tsequence: [\n\t\t{\n\t\t\tid: instancePageStateVersions.AddCroppingId,\n\t\t\tup(instance: any) {\n\t\t\t\tinstance.croppingShapeId = null\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RemoveInstanceIdAndCameraId,\n\t\t\tup(instance: any) {\n\t\t\t\tdelete instance.instanceId\n\t\t\t\tdelete instance.cameraId\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.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: instancePageStateVersions.RenameProperties,\n\t\t\t// this migration is cursed: it was written wrong and doesn't do anything.\n\t\t\t// rather than replace it, I've added another migration below that fixes it.\n\t\t\tup: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RenamePropertiesAgain,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.selectedShapeIds = record.selectedIds\n\t\t\t\tdelete record.selectedIds\n\t\t\t\trecord.hintingShapeIds = record.hintingIds\n\t\t\t\tdelete record.hintingIds\n\t\t\t\trecord.erasingShapeIds = record.erasingIds\n\t\t\t\tdelete record.erasingIds\n\t\t\t\trecord.hoveredShapeId = record.hoveredId\n\t\t\t\tdelete record.hoveredId\n\t\t\t\trecord.editingShapeId = record.editingId\n\t\t\t\tdelete record.editingId\n\t\t\t\trecord.croppingShapeId = record.croppingShapeId ?? record.croppingId ?? null\n\t\t\t\tdelete record.croppingId\n\t\t\t\trecord.focusedGroupId = record.focusLayerId\n\t\t\t\tdelete record.focusLayerId\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\trecord.selectedIds = record.selectedShapeIds\n\t\t\t\tdelete record.selectedShapeIds\n\t\t\t\trecord.hintingIds = record.hintingShapeIds\n\t\t\t\tdelete record.hintingShapeIds\n\t\t\t\trecord.erasingIds = record.erasingShapeIds\n\t\t\t\tdelete record.erasingShapeIds\n\t\t\t\trecord.hoveredId = record.hoveredShapeId\n\t\t\t\tdelete record.hoveredShapeId\n\t\t\t\trecord.editingId = record.editingShapeId\n\t\t\t\tdelete record.editingShapeId\n\t\t\t\trecord.croppingId = record.croppingShapeId\n\t\t\t\tdelete record.croppingShapeId\n\t\t\t\trecord.focusLayerId = record.focusedGroupId\n\t\t\t\tdelete record.focusedGroupId\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The RecordType definition for TLInstancePageState records. Defines validation,\n * scope, and default properties for instance page state records.\n *\n * Instance page states are scoped to the session level, meaning they are\n * specific to a browser tab and don't persist across sessions or sync\n * in collaborative environments.\n *\n * @example\n * ```ts\n * const pageState = InstancePageStateRecordType.create({\n * id: 'instance_page_state:page1',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1']\n * })\n * ```\n *\n * @public\n */\nexport const InstancePageStateRecordType = createRecordType<TLInstancePageState>(\n\t'instance_page_state',\n\t{\n\t\tvalidator: instancePageStateValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tpageId: false,\n\t\t\tselectedShapeIds: false,\n\t\t\teditingShapeId:
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEC;AAAA,EACA;AAAA,EACA;AAAA,OAEM;AAEP,SAAS,SAAS;AAClB,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AACjC,SAAS,uBAA+B;AA2DjC,MAAM,6BAA+D,EAAE;AAAA,EAC7E;AAAA,EACA,EAAE,OAAO;AAAA,IACR,UAAU,EAAE,QAAQ,qBAAqB;AAAA,IACzC,IAAI,YAAmC,qBAAqB;AAAA,IAC5D,QAAQ;AAAA,IACR,kBAAkB,EAAE,QAAQ,gBAAgB;AAAA,IAC5C,iBAAiB,EAAE,QAAQ,gBAAgB;AAAA,IAC3C,iBAAiB,EAAE,QAAQ,gBAAgB;AAAA,IAC3C,gBAAgB,iBAAiB,SAAS;AAAA,IAC1C,gBAAgB,iBAAiB,SAAS;AAAA,IAC1C,iBAAiB,iBAAiB,SAAS;AAAA,IAC3C,gBAAgB,iBAAiB,SAAS;AAAA,IAC1C,MAAM,EAAE;AAAA,EACT,CAAC;AACF;AASO,MAAM,4BAA4B,mBAAmB,kCAAkC;AAAA,EAC7F,eAAe;AAAA,EACf,6BAA6B;AAAA,EAC7B,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,uBAAuB;AACxB,CAAU;AAeH,MAAM,8BAA8B,8BAA8B;AAAA,EACxE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,IACT;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,GAAG,UAAe;AACjB,iBAAS,kBAAkB;AAAA,MAC5B;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,GAAG,UAAe;AACjB,eAAO,SAAS;AAChB,eAAO,SAAS;AAAA,MACjB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,IAAI,CAAC,WAAgB;AACpB,eAAO,OAAO,CAAC;AAAA,MAChB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA;AAAA;AAAA,MAG9B,IAAI,CAAC,YAAY;AAAA,MAEjB;AAAA,MACA,MAAM,CAAC,YAAY;AAAA,MAEnB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,0BAA0B;AAAA,MAC9B,IAAI,CAAC,WAAgB;AACpB,eAAO,mBAAmB,OAAO;AACjC,eAAO,OAAO;AACd,eAAO,kBAAkB,OAAO;AAChC,eAAO,OAAO;AACd,eAAO,kBAAkB,OAAO;AAChC,eAAO,OAAO;AACd,eAAO,iBAAiB,OAAO;AAC/B,eAAO,OAAO;AACd,eAAO,iBAAiB,OAAO;AAC/B,eAAO,OAAO;AACd,eAAO,kBAAkB,OAAO,mBAAmB,OAAO,cAAc;AACxE,eAAO,OAAO;AACd,eAAO,iBAAiB,OAAO;AAC/B,eAAO,OAAO;AAAA,MACf;AAAA,MACA,MAAM,CAAC,WAAgB;AACtB,eAAO,cAAc,OAAO;AAC5B,eAAO,OAAO;AACd,eAAO,aAAa,OAAO;AAC3B,eAAO,OAAO;AACd,eAAO,aAAa,OAAO;AAC3B,eAAO,OAAO;AACd,eAAO,YAAY,OAAO;AAC1B,eAAO,OAAO;AACd,eAAO,YAAY,OAAO;AAC1B,eAAO,OAAO;AACd,eAAO,aAAa,OAAO;AAC3B,eAAO,OAAO;AACd,eAAO,eAAe,OAAO;AAC7B,eAAO,OAAO;AAAA,MACf;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAqBM,MAAM,8BAA8B;AAAA,EAC1C;AAAA,EACA;AAAA,IACC,WAAW;AAAA,IACX,OAAO;AAAA,IACP,eAAe;AAAA,MACd,QAAQ;AAAA,MACR,kBAAkB;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { shapeIdValidator } from '../shapes/TLBaseShape'\nimport { pageIdValidator, TLPage } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * State that is unique to a particular page within a particular browser tab.\n * This record tracks all page-specific interaction state including selected shapes,\n * editing state, hover state, and other transient UI state that is tied to\n * both a specific page and a specific browser session.\n *\n * Each combination of page and browser tab has its own TLInstancePageState record.\n *\n * @example\n * ```ts\n * const pageState: TLInstancePageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1', 'shape:circle2'],\n * hoveredShapeId: 'shape:text3',\n * editingShapeId: null,\n * focusedGroupId: null\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePageState extends BaseRecord<\n\t'instance_page_state',\n\tTLInstancePageStateId\n> {\n\tpageId: RecordId<TLPage>\n\tselectedShapeIds: TLShapeId[]\n\thintingShapeIds: TLShapeId[]\n\terasingShapeIds: TLShapeId[]\n\thoveredShapeId: TLShapeId | null\n\teditingShapeId: TLShapeId | null\n\tcroppingShapeId: TLShapeId | null\n\tfocusedGroupId: TLShapeId | null\n\tmeta: JsonObject\n}\n\n/**\n * Runtime validator for TLInstancePageState records. Validates the structure\n * and types of all instance page state properties to ensure data integrity.\n *\n * @example\n * ```ts\n * const pageState = {\n * id: 'instance_page_state:page1',\n * typeName: 'instance_page_state',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1'],\n * // ... other properties\n * }\n * const isValid = instancePageStateValidator.isValid(pageState) // true\n * ```\n *\n * @public\n */\nexport const instancePageStateValidator: T.Validator<TLInstancePageState> = T.model(\n\t'instance_page_state',\n\tT.object({\n\t\ttypeName: T.literal('instance_page_state'),\n\t\tid: idValidator<TLInstancePageStateId>('instance_page_state'),\n\t\tpageId: pageIdValidator,\n\t\tselectedShapeIds: T.arrayOf(shapeIdValidator),\n\t\thintingShapeIds: T.arrayOf(shapeIdValidator),\n\t\terasingShapeIds: T.arrayOf(shapeIdValidator),\n\t\thoveredShapeId: shapeIdValidator.nullable(),\n\t\teditingShapeId: shapeIdValidator.nullable(),\n\t\tcroppingShapeId: shapeIdValidator.nullable(),\n\t\tfocusedGroupId: shapeIdValidator.nullable(),\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n)\n\n/**\n * Migration version identifiers for TLInstancePageState records. Each version\n * represents a schema change that requires data transformation when loading\n * older documents.\n *\n * @public\n */\nexport const instancePageStateVersions = createMigrationIds('com.tldraw.instance_page_state', {\n\tAddCroppingId: 1,\n\tRemoveInstanceIdAndCameraId: 2,\n\tAddMeta: 3,\n\tRenameProperties: 4,\n\tRenamePropertiesAgain: 5,\n} as const)\n\n/**\n * Migration sequence for TLInstancePageState records. Defines how to transform\n * instance page state records between different schema versions, ensuring data\n * compatibility when loading documents created with different versions.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migrated = instancePageStateMigrations.migrate(oldState, targetVersion)\n * ```\n *\n * @public\n */\nexport const instancePageStateMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance_page_state',\n\trecordType: 'instance_page_state',\n\tsequence: [\n\t\t{\n\t\t\tid: instancePageStateVersions.AddCroppingId,\n\t\t\tup(instance: any) {\n\t\t\t\tinstance.croppingShapeId = null\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RemoveInstanceIdAndCameraId,\n\t\t\tup(instance: any) {\n\t\t\t\tdelete instance.instanceId\n\t\t\t\tdelete instance.cameraId\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.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: instancePageStateVersions.RenameProperties,\n\t\t\t// this migration is cursed: it was written wrong and doesn't do anything.\n\t\t\t// rather than replace it, I've added another migration below that fixes it.\n\t\t\tup: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (_record) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePageStateVersions.RenamePropertiesAgain,\n\t\t\tup: (record: any) => {\n\t\t\t\trecord.selectedShapeIds = record.selectedIds\n\t\t\t\tdelete record.selectedIds\n\t\t\t\trecord.hintingShapeIds = record.hintingIds\n\t\t\t\tdelete record.hintingIds\n\t\t\t\trecord.erasingShapeIds = record.erasingIds\n\t\t\t\tdelete record.erasingIds\n\t\t\t\trecord.hoveredShapeId = record.hoveredId\n\t\t\t\tdelete record.hoveredId\n\t\t\t\trecord.editingShapeId = record.editingId\n\t\t\t\tdelete record.editingId\n\t\t\t\trecord.croppingShapeId = record.croppingShapeId ?? record.croppingId ?? null\n\t\t\t\tdelete record.croppingId\n\t\t\t\trecord.focusedGroupId = record.focusLayerId\n\t\t\t\tdelete record.focusLayerId\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\trecord.selectedIds = record.selectedShapeIds\n\t\t\t\tdelete record.selectedShapeIds\n\t\t\t\trecord.hintingIds = record.hintingShapeIds\n\t\t\t\tdelete record.hintingShapeIds\n\t\t\t\trecord.erasingIds = record.erasingShapeIds\n\t\t\t\tdelete record.erasingShapeIds\n\t\t\t\trecord.hoveredId = record.hoveredShapeId\n\t\t\t\tdelete record.hoveredShapeId\n\t\t\t\trecord.editingId = record.editingShapeId\n\t\t\t\tdelete record.editingShapeId\n\t\t\t\trecord.croppingId = record.croppingShapeId\n\t\t\t\tdelete record.croppingShapeId\n\t\t\t\trecord.focusLayerId = record.focusedGroupId\n\t\t\t\tdelete record.focusedGroupId\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The RecordType definition for TLInstancePageState records. Defines validation,\n * scope, and default properties for instance page state records.\n *\n * Instance page states are scoped to the session level, meaning they are\n * specific to a browser tab and don't persist across sessions or sync\n * in collaborative environments.\n *\n * @example\n * ```ts\n * const pageState = InstancePageStateRecordType.create({\n * id: 'instance_page_state:page1',\n * pageId: 'page:page1',\n * selectedShapeIds: ['shape:rect1']\n * })\n * ```\n *\n * @public\n */\nexport const InstancePageStateRecordType = createRecordType<TLInstancePageState>(\n\t'instance_page_state',\n\t{\n\t\tvalidator: instancePageStateValidator,\n\t\tscope: 'session',\n\t\tephemeralKeys: {\n\t\t\tpageId: false,\n\t\t\tselectedShapeIds: false,\n\t\t\t// editingShapeId is set with `history: 'ignore'`, so entering the editing\n\t\t\t// state is never undoable. Marking it ephemeral keeps undo/redo from\n\t\t\t// reapplying a stale editingShapeId (e.g. after a shape it pointed at was\n\t\t\t// deleted), which could leave the editor pointing at a missing shape.\n\t\t\teditingShapeId: true,\n\t\t\tcroppingShapeId: false,\n\t\t\tmeta: false,\n\n\t\t\thintingShapeIds: true,\n\t\t\terasingShapeIds: true,\n\t\t\thoveredShapeId: true,\n\t\t\tfocusedGroupId: true,\n\t\t},\n\t}\n).withDefaultProperties(\n\t(): Omit<TLInstancePageState, 'id' | 'typeName' | 'pageId'> => ({\n\t\teditingShapeId: null,\n\t\tcroppingShapeId: null,\n\t\tselectedShapeIds: [],\n\t\thoveredShapeId: null,\n\t\terasingShapeIds: [],\n\t\thintingShapeIds: [],\n\t\tfocusedGroupId: null,\n\t\tmeta: {},\n\t})\n)\n\n/**\n * A unique identifier for TLInstancePageState records.\n *\n * Instance page state IDs follow the format 'instance_page_state:' followed\n * by a unique identifier, typically related to the page ID.\n *\n * @example\n * ```ts\n * const stateId: TLInstancePageStateId = 'instance_page_state:page1'\n * ```\n *\n * @public\n */\nexport type TLInstancePageStateId = RecordId<TLInstancePageState>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -8,15 +8,16 @@ import { boxModelValidator } from "../misc/geometry-types.mjs";
|
|
|
8
8
|
import { idValidator } from "../misc/id-validator.mjs";
|
|
9
9
|
import { cursorTypeValidator } from "../misc/TLCursor.mjs";
|
|
10
10
|
import { scribbleValidator } from "../misc/TLScribble.mjs";
|
|
11
|
+
import { userIdValidator } from "./TLUser.mjs";
|
|
11
12
|
const instancePresenceValidator = T.model(
|
|
12
13
|
"instance_presence",
|
|
13
14
|
T.object({
|
|
14
15
|
typeName: T.literal("instance_presence"),
|
|
15
16
|
id: idValidator("instance_presence"),
|
|
16
|
-
userId:
|
|
17
|
+
userId: userIdValidator,
|
|
17
18
|
userName: T.string,
|
|
18
19
|
lastActivityTimestamp: T.number.nullable(),
|
|
19
|
-
followingUserId:
|
|
20
|
+
followingUserId: userIdValidator.nullable(),
|
|
20
21
|
cursor: T.object({
|
|
21
22
|
x: T.number,
|
|
22
23
|
y: T.number,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/records/TLPresence.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorTypeValidator, TLCursor } from '../misc/TLCursor'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\n\n/**\n * Represents the presence state of a user in a collaborative tldraw session.\n * This record tracks what another user is doing: their cursor position, selected\n * shapes, current page, and other real-time activity indicators.\n *\n * Instance presence records are used in multiplayer environments to show\n * where other collaborators are working and what they're doing.\n *\n * @example\n * ```ts\n * const presence: TLInstancePresence = {\n * id: 'instance_presence:user123',\n * typeName: 'instance_presence',\n * userId: 'user123',\n * userName: 'Alice',\n * color: '#FF6B6B',\n * cursor: { x: 100, y: 150, type: 'default', rotation: 0 },\n * currentPageId: 'page:main',\n * selectedShapeIds: ['shape:rect1']\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {\n\tuserId:
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEC;AAAA,EACA;AAAA,EACA;AAAA,OAEM;AAEP,SAAS,SAAS;AAClB,SAAmB,yBAAyB;AAC5C,SAAS,mBAAmB;AAC5B,SAAS,2BAAqC;AAC9C,SAAS,yBAAqC;
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseRecord,\n\tcreateMigrationIds,\n\tcreateRecordMigrationSequence,\n\tcreateRecordType,\n\tRecordId,\n} from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { BoxModel, boxModelValidator } from '../misc/geometry-types'\nimport { idValidator } from '../misc/id-validator'\nimport { cursorTypeValidator, TLCursor } from '../misc/TLCursor'\nimport { scribbleValidator, TLScribble } from '../misc/TLScribble'\nimport { TLPageId } from './TLPage'\nimport { TLShapeId } from './TLShape'\nimport { TLUserId, userIdValidator } from './TLUser'\n\n/**\n * Represents the presence state of a user in a collaborative tldraw session.\n * This record tracks what another user is doing: their cursor position, selected\n * shapes, current page, and other real-time activity indicators.\n *\n * Instance presence records are used in multiplayer environments to show\n * where other collaborators are working and what they're doing.\n *\n * @example\n * ```ts\n * const presence: TLInstancePresence = {\n * id: 'instance_presence:user123',\n * typeName: 'instance_presence',\n * userId: 'user123',\n * userName: 'Alice',\n * color: '#FF6B6B',\n * cursor: { x: 100, y: 150, type: 'default', rotation: 0 },\n * currentPageId: 'page:main',\n * selectedShapeIds: ['shape:rect1']\n * }\n * ```\n *\n * @public\n */\nexport interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {\n\tuserId: TLUserId\n\tuserName: string\n\tlastActivityTimestamp: number | null\n\tcolor: string // can be any hex color\n\tcamera: { x: number; y: number; z: number } | null\n\tselectedShapeIds: TLShapeId[]\n\tcurrentPageId: TLPageId\n\tbrush: BoxModel | null\n\tscribbles: TLScribble[]\n\tscreenBounds: BoxModel | null\n\tfollowingUserId: TLUserId | null\n\tcursor: {\n\t\tx: number\n\t\ty: number\n\t\ttype: TLCursor['type']\n\t\trotation: number\n\t} | null\n\tchatMessage: string\n\tmeta: JsonObject\n}\n\n/**\n * A unique identifier for TLInstancePresence records.\n *\n * Instance presence IDs follow the format 'instance_presence:' followed\n * by a unique identifier, typically the user ID.\n *\n * @example\n * ```ts\n * const presenceId: TLInstancePresenceID = 'instance_presence:user123'\n * ```\n *\n * @public\n */\nexport type TLInstancePresenceID = RecordId<TLInstancePresence>\n\n/**\n * Runtime validator for TLInstancePresence records. Validates the structure\n * and types of all instance presence properties to ensure data integrity.\n *\n * @example\n * ```ts\n * const presence = {\n * id: 'instance_presence:user1',\n * typeName: 'instance_presence',\n * userId: 'user1',\n * userName: 'John',\n * color: '#007AFF',\n * cursor: { x: 0, y: 0, type: 'default', rotation: 0 },\n * currentPageId: 'page:main',\n * selectedShapeIds: []\n * }\n * const isValid = instancePresenceValidator.isValid(presence) // true\n * ```\n *\n * @public\n */\nexport const instancePresenceValidator: T.Validator<TLInstancePresence> = T.model(\n\t'instance_presence',\n\tT.object({\n\t\ttypeName: T.literal('instance_presence'),\n\t\tid: idValidator<TLInstancePresenceID>('instance_presence'),\n\t\tuserId: userIdValidator,\n\t\tuserName: T.string,\n\t\tlastActivityTimestamp: T.number.nullable(),\n\t\tfollowingUserId: userIdValidator.nullable(),\n\t\tcursor: T.object({\n\t\t\tx: T.number,\n\t\t\ty: T.number,\n\t\t\ttype: cursorTypeValidator,\n\t\t\trotation: T.number,\n\t\t}).nullable(),\n\t\tcolor: T.string,\n\t\tcamera: T.object({\n\t\t\tx: T.number,\n\t\t\ty: T.number,\n\t\t\tz: T.number,\n\t\t}).nullable(),\n\t\tscreenBounds: boxModelValidator.nullable(),\n\t\tselectedShapeIds: T.arrayOf(idValidator<TLShapeId>('shape')),\n\t\tcurrentPageId: idValidator<TLPageId>('page'),\n\t\tbrush: boxModelValidator.nullable(),\n\t\tscribbles: T.arrayOf(scribbleValidator),\n\t\tchatMessage: T.string,\n\t\tmeta: T.jsonValue as T.ObjectValidator<JsonObject>,\n\t})\n)\n\n/**\n * Migration version identifiers for TLInstancePresence records. Each version\n * represents a schema change that requires data transformation when loading\n * older documents.\n *\n * @public\n */\nexport const instancePresenceVersions = createMigrationIds('com.tldraw.instance_presence', {\n\tAddScribbleDelay: 1,\n\tRemoveInstanceId: 2,\n\tAddChatMessage: 3,\n\tAddMeta: 4,\n\tRenameSelectedShapeIds: 5,\n\tNullableCameraCursor: 6,\n} as const)\n\n/**\n * Migration sequence for TLInstancePresence records. Defines how to transform\n * instance presence records between different schema versions, ensuring data\n * compatibility when loading documents created with different versions.\n *\n * @example\n * ```ts\n * // Migrations are applied automatically when loading documents\n * const migrated = instancePresenceMigrations.migrate(oldPresence, targetVersion)\n * ```\n *\n * @public\n */\nexport const instancePresenceMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.instance_presence',\n\trecordType: 'instance_presence',\n\tsequence: [\n\t\t{\n\t\t\tid: instancePresenceVersions.AddScribbleDelay,\n\t\t\tup: (instance: any) => {\n\t\t\t\tif (instance.scribble !== null) {\n\t\t\t\t\tinstance.scribble.delay = 0\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.RemoveInstanceId,\n\t\t\tup: (instance: any) => {\n\t\t\t\tdelete instance.instanceId\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.AddChatMessage,\n\t\t\tup: (instance: any) => {\n\t\t\t\tinstance.chatMessage = ''\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.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: instancePresenceVersions.RenameSelectedShapeIds,\n\t\t\tup: (_record) => {\n\t\t\t\t// noop, whoopsie\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: instancePresenceVersions.NullableCameraCursor,\n\t\t\tup: (_record: any) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t\tdown: (record: any) => {\n\t\t\t\tif (record.camera === null) {\n\t\t\t\t\trecord.camera = { x: 0, y: 0, z: 1 }\n\t\t\t\t}\n\t\t\t\tif (record.lastActivityTimestamp === null) {\n\t\t\t\t\trecord.lastActivityTimestamp = 0\n\t\t\t\t}\n\t\t\t\tif (record.cursor === null) {\n\t\t\t\t\trecord.cursor = { type: 'default', x: 0, y: 0, rotation: 0 }\n\t\t\t\t}\n\t\t\t\tif (record.screenBounds === null) {\n\t\t\t\t\trecord.screenBounds = { x: 0, y: 0, w: 1, h: 1 }\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n\n/**\n * The RecordType definition for TLInstancePresence records. Defines validation,\n * scope, and default properties for instance presence records.\n *\n * Instance presence records are scoped to the presence level, meaning they\n * represent real-time collaborative state that is ephemeral and tied to\n * active user sessions.\n *\n * @example\n * ```ts\n * const presence = InstancePresenceRecordType.create({\n * id: 'instance_presence:user1',\n * userId: 'user1',\n * userName: 'Alice',\n * color: '#FF6B6B',\n * currentPageId: 'page:main'\n * })\n * ```\n *\n * @public\n */\nexport const InstancePresenceRecordType = createRecordType<TLInstancePresence>(\n\t'instance_presence',\n\t{\n\t\tvalidator: instancePresenceValidator,\n\t\tscope: 'presence',\n\t}\n).withDefaultProperties(() => ({\n\tlastActivityTimestamp: null,\n\tfollowingUserId: null,\n\tcolor: '#FF0000',\n\tcamera: null,\n\tcursor: null,\n\tscreenBounds: null,\n\tselectedShapeIds: [],\n\tbrush: null,\n\tscribbles: [],\n\tchatMessage: '',\n\tmeta: {},\n}))\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/tlschema",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (schema).",
|
|
4
|
-
"version": "5.2.0-canary.
|
|
4
|
+
"version": "5.2.0-canary.463b08fade11",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -51,15 +51,18 @@
|
|
|
51
51
|
"vitest": "^4.1.7"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@tldraw/state": "5.2.0-canary.
|
|
55
|
-
"@tldraw/store": "5.2.0-canary.
|
|
56
|
-
"@tldraw/utils": "5.2.0-canary.
|
|
57
|
-
"@tldraw/validate": "5.2.0-canary.
|
|
54
|
+
"@tldraw/state": "5.2.0-canary.463b08fade11",
|
|
55
|
+
"@tldraw/store": "5.2.0-canary.463b08fade11",
|
|
56
|
+
"@tldraw/utils": "5.2.0-canary.463b08fade11",
|
|
57
|
+
"@tldraw/validate": "5.2.0-canary.463b08fade11"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"react": "^18.2.0 || ^19.2.1",
|
|
61
61
|
"react-dom": "^18.2.0 || ^19.2.1"
|
|
62
62
|
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=22.12.0"
|
|
65
|
+
},
|
|
63
66
|
"module": "dist-esm/index.mjs",
|
|
64
67
|
"source": "src/index.ts",
|
|
65
68
|
"exports": {
|
|
@@ -15,6 +15,7 @@ import { scribbleValidator, TLScribble } from '../misc/TLScribble'
|
|
|
15
15
|
import { StyleProp } from '../styles/StyleProp'
|
|
16
16
|
import { pageIdValidator, TLPageId } from './TLPage'
|
|
17
17
|
import { TLShapeId } from './TLShape'
|
|
18
|
+
import { TLUserId, userIdValidator } from './TLUser'
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* State that is particular to a single browser tab. The TLInstance record stores
|
|
@@ -43,8 +44,8 @@ export interface TLInstance extends BaseRecord<'instance', TLInstanceId> {
|
|
|
43
44
|
currentPageId: TLPageId
|
|
44
45
|
opacityForNextShape: TLOpacityType
|
|
45
46
|
stylesForNextShape: Record<string, unknown>
|
|
46
|
-
followingUserId:
|
|
47
|
-
highlightedUserIds:
|
|
47
|
+
followingUserId: TLUserId | null
|
|
48
|
+
highlightedUserIds: TLUserId[]
|
|
48
49
|
brush: BoxModel | null
|
|
49
50
|
cursor: TLCursor
|
|
50
51
|
scribbles: TLScribble[]
|
|
@@ -211,7 +212,7 @@ export function createInstanceRecordType(stylesById: Map<string, StyleProp<unkno
|
|
|
211
212
|
typeName: T.literal('instance'),
|
|
212
213
|
id: idValidator<TLInstanceId>('instance'),
|
|
213
214
|
currentPageId: pageIdValidator,
|
|
214
|
-
followingUserId:
|
|
215
|
+
followingUserId: userIdValidator.nullable(),
|
|
215
216
|
brush: boxModelValidator.nullable(),
|
|
216
217
|
opacityForNextShape: opacityValidator,
|
|
217
218
|
stylesForNextShape: T.object(stylesForNextShapeValidators),
|
|
@@ -228,7 +229,7 @@ export function createInstanceRecordType(stylesById: Map<string, StyleProp<unkno
|
|
|
228
229
|
isGridMode: T.boolean,
|
|
229
230
|
chatMessage: T.string,
|
|
230
231
|
isChatting: T.boolean,
|
|
231
|
-
highlightedUserIds: T.arrayOf(
|
|
232
|
+
highlightedUserIds: T.arrayOf(userIdValidator),
|
|
232
233
|
isFocused: T.boolean,
|
|
233
234
|
devicePixelRatio: T.number,
|
|
234
235
|
isCoarsePointer: T.boolean,
|
|
@@ -212,7 +212,11 @@ export const InstancePageStateRecordType = createRecordType<TLInstancePageState>
|
|
|
212
212
|
ephemeralKeys: {
|
|
213
213
|
pageId: false,
|
|
214
214
|
selectedShapeIds: false,
|
|
215
|
-
editingShapeId:
|
|
215
|
+
// editingShapeId is set with `history: 'ignore'`, so entering the editing
|
|
216
|
+
// state is never undoable. Marking it ephemeral keeps undo/redo from
|
|
217
|
+
// reapplying a stale editingShapeId (e.g. after a shape it pointed at was
|
|
218
|
+
// deleted), which could leave the editor pointing at a missing shape.
|
|
219
|
+
editingShapeId: true,
|
|
216
220
|
croppingShapeId: false,
|
|
217
221
|
meta: false,
|
|
218
222
|
|
|
@@ -13,6 +13,7 @@ import { cursorTypeValidator, TLCursor } from '../misc/TLCursor'
|
|
|
13
13
|
import { scribbleValidator, TLScribble } from '../misc/TLScribble'
|
|
14
14
|
import { TLPageId } from './TLPage'
|
|
15
15
|
import { TLShapeId } from './TLShape'
|
|
16
|
+
import { TLUserId, userIdValidator } from './TLUser'
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Represents the presence state of a user in a collaborative tldraw session.
|
|
@@ -39,7 +40,7 @@ import { TLShapeId } from './TLShape'
|
|
|
39
40
|
* @public
|
|
40
41
|
*/
|
|
41
42
|
export interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {
|
|
42
|
-
userId:
|
|
43
|
+
userId: TLUserId
|
|
43
44
|
userName: string
|
|
44
45
|
lastActivityTimestamp: number | null
|
|
45
46
|
color: string // can be any hex color
|
|
@@ -49,7 +50,7 @@ export interface TLInstancePresence extends BaseRecord<'instance_presence', TLIn
|
|
|
49
50
|
brush: BoxModel | null
|
|
50
51
|
scribbles: TLScribble[]
|
|
51
52
|
screenBounds: BoxModel | null
|
|
52
|
-
followingUserId:
|
|
53
|
+
followingUserId: TLUserId | null
|
|
53
54
|
cursor: {
|
|
54
55
|
x: number
|
|
55
56
|
y: number
|
|
@@ -101,10 +102,10 @@ export const instancePresenceValidator: T.Validator<TLInstancePresence> = T.mode
|
|
|
101
102
|
T.object({
|
|
102
103
|
typeName: T.literal('instance_presence'),
|
|
103
104
|
id: idValidator<TLInstancePresenceID>('instance_presence'),
|
|
104
|
-
userId:
|
|
105
|
+
userId: userIdValidator,
|
|
105
106
|
userName: T.string,
|
|
106
107
|
lastActivityTimestamp: T.number.nullable(),
|
|
107
|
-
followingUserId:
|
|
108
|
+
followingUserId: userIdValidator.nullable(),
|
|
108
109
|
cursor: T.object({
|
|
109
110
|
x: T.number,
|
|
110
111
|
y: T.number,
|