{
  "version": 3,
  "sources": ["../src/store-migrations.ts"],
  "sourcesContent": ["import { createMigrationIds, createMigrationSequence } from '@tldraw/store'\nimport { IndexKey, objectMapEntries } from '@tldraw/utils'\nimport { TLPage } from './records/TLPage'\nimport { TLShape } from './records/TLShape'\nimport { TLLineShape } from './shapes/TLLineShape'\n\n/**\n * Migration version constants for store-level schema changes.\n * Each version represents a breaking change that requires data transformation.\n *\n * @internal\n */\nconst Versions = createMigrationIds('com.tldraw.store', {\n\tRemoveCodeAndIconShapeTypes: 1,\n\tAddInstancePresenceType: 2,\n\tRemoveTLUserAndPresenceAndAddPointer: 3,\n\tRemoveUserDocument: 4,\n\tFixIndexKeys: 5,\n} as const)\n\n/**\n * Migration version identifiers for store-level migrations.\n * These versions track changes to the overall store structure and data model.\n *\n * @example\n * ```ts\n * import { storeVersions } from '@tldraw/tlschema'\n *\n * // Check if a specific migration version exists\n * const hasRemoveCodeShapes = storeVersions.RemoveCodeAndIconShapeTypes\n * ```\n *\n * @public\n */\nexport { Versions as storeVersions }\n\n/**\n * Store-level migration sequence that handles evolution of the tldraw data model.\n * These migrations run when the store schema version changes and ensure backward\n * compatibility by transforming old data structures to new formats.\n *\n * The migrations handle:\n * - Removal of deprecated shape types (code, icon)\n * - Addition of new record types (instance presence)\n * - Cleanup of obsolete user and presence data\n * - Removal of deprecated user document records\n *\n * @example\n * ```ts\n * import { storeMigrations } from '@tldraw/tlschema'\n * import { migrate } from '@tldraw/store'\n *\n * // Apply store migrations to old data\n * const migratedStore = migrate({\n *   store: oldStoreData,\n *   migrations: storeMigrations,\n *   fromVersion: 0,\n *   toVersion: storeMigrations.currentVersion\n * })\n * ```\n *\n * @public\n */\nexport const storeMigrations = createMigrationSequence({\n\tsequenceId: 'com.tldraw.store',\n\tretroactive: false,\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.RemoveCodeAndIconShapeTypes,\n\t\t\tscope: 'storage',\n\t\t\tup: (storage) => {\n\t\t\t\tfor (const [id, record] of storage.entries()) {\n\t\t\t\t\tif (\n\t\t\t\t\t\trecord.typeName === 'shape' &&\n\t\t\t\t\t\t'type' in record &&\n\t\t\t\t\t\t(record.type === 'icon' || record.type === 'code')\n\t\t\t\t\t) {\n\t\t\t\t\t\tstorage.delete(id)\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: Versions.AddInstancePresenceType,\n\t\t\tscope: 'storage',\n\t\t\tup(_storage) {\n\t\t\t\t// noop\n\t\t\t\t// there used to be a down migration for this but we made down migrations optional\n\t\t\t\t// and we don't use them on storage-level migrations so we can just remove it\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t// remove user and presence records and add pointer records\n\t\t\tid: Versions.RemoveTLUserAndPresenceAndAddPointer,\n\t\t\tscope: 'storage',\n\t\t\tup: (storage) => {\n\t\t\t\tfor (const [id, record] of storage.entries()) {\n\t\t\t\t\tif (record.typeName.match(/^(user|user_presence)$/)) {\n\t\t\t\t\t\tstorage.delete(id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t// remove user document records\n\t\t\tid: Versions.RemoveUserDocument,\n\t\t\tscope: 'storage',\n\t\t\tup: (storage) => {\n\t\t\t\tfor (const [id, record] of storage.entries()) {\n\t\t\t\t\tif (record.typeName.match('user_document')) {\n\t\t\t\t\t\tstorage.delete(id)\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: Versions.FixIndexKeys,\n\t\t\tscope: 'record',\n\t\t\tup: (record) => {\n\t\t\t\tif (['shape', 'page'].includes(record.typeName) && 'index' in record) {\n\t\t\t\t\tconst recordWithIndex = record as TLShape | TLPage\n\t\t\t\t\t// Our newer fractional indexed library (more correctly) validates that indices\n\t\t\t\t\t// do not end with 0. ('a0' being an exception)\n\t\t\t\t\tif (recordWithIndex.index.endsWith('0') && recordWithIndex.index !== 'a0') {\n\t\t\t\t\t\trecordWithIndex.index = (recordWithIndex.index.slice(0, -1) +\n\t\t\t\t\t\t\tgetNRandomBase62Digits(3)) as IndexKey\n\t\t\t\t\t}\n\t\t\t\t\t// Line shapes have 'points' that have indices as well.\n\t\t\t\t\tif (record.typeName === 'shape' && (recordWithIndex as TLShape).type === 'line') {\n\t\t\t\t\t\tconst lineShape = recordWithIndex as TLLineShape\n\t\t\t\t\t\tfor (const [_, point] of objectMapEntries(lineShape.props.points)) {\n\t\t\t\t\t\t\tif (point.index.endsWith('0') && point.index !== 'a0') {\n\t\t\t\t\t\t\t\tpoint.index = (point.index.slice(0, -1) + getNRandomBase62Digits(3)) as IndexKey\n\t\t\t\t\t\t\t}\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\tdown: () => {\n\t\t\t\t// noop\n\t\t\t\t// Enables tlsync to support older clients so as to not force people to refresh immediately after deploying.\n\t\t\t},\n\t\t},\n\t],\n})\n\nconst BASE_62_DIGITS_WITHOUT_ZERO = '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'\nconst getRandomBase62Digit = () => {\n\treturn BASE_62_DIGITS_WITHOUT_ZERO.charAt(\n\t\tMath.floor(Math.random() * BASE_62_DIGITS_WITHOUT_ZERO.length)\n\t)\n}\n\nconst getNRandomBase62Digits = (n: number) => {\n\treturn Array.from({ length: n }, getRandomBase62Digit).join('')\n}\n"],
  "mappings": "AAAA,SAAS,oBAAoB,+BAA+B;AAC5D,SAAmB,wBAAwB;AAW3C,MAAM,WAAW,mBAAmB,oBAAoB;AAAA,EACvD,6BAA6B;AAAA,EAC7B,yBAAyB;AAAA,EACzB,sCAAsC;AAAA,EACtC,oBAAoB;AAAA,EACpB,cAAc;AACf,CAAU;AA6CH,MAAM,kBAAkB,wBAAwB;AAAA,EACtD,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,OAAO;AAAA,MACP,IAAI,CAAC,YAAY;AAChB,mBAAW,CAAC,IAAI,MAAM,KAAK,QAAQ,QAAQ,GAAG;AAC7C,cACC,OAAO,aAAa,WACpB,UAAU,WACT,OAAO,SAAS,UAAU,OAAO,SAAS,SAC1C;AACD,oBAAQ,OAAO,EAAE;AAAA,UAClB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,OAAO;AAAA,MACP,GAAG,UAAU;AAAA,MAIb;AAAA,IACD;AAAA,IACA;AAAA;AAAA,MAEC,IAAI,SAAS;AAAA,MACb,OAAO;AAAA,MACP,IAAI,CAAC,YAAY;AAChB,mBAAW,CAAC,IAAI,MAAM,KAAK,QAAQ,QAAQ,GAAG;AAC7C,cAAI,OAAO,SAAS,MAAM,wBAAwB,GAAG;AACpD,oBAAQ,OAAO,EAAE;AAAA,UAClB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA;AAAA,MAEC,IAAI,SAAS;AAAA,MACb,OAAO;AAAA,MACP,IAAI,CAAC,YAAY;AAChB,mBAAW,CAAC,IAAI,MAAM,KAAK,QAAQ,QAAQ,GAAG;AAC7C,cAAI,OAAO,SAAS,MAAM,eAAe,GAAG;AAC3C,oBAAQ,OAAO,EAAE;AAAA,UAClB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,OAAO;AAAA,MACP,IAAI,CAAC,WAAW;AACf,YAAI,CAAC,SAAS,MAAM,EAAE,SAAS,OAAO,QAAQ,KAAK,WAAW,QAAQ;AACrE,gBAAM,kBAAkB;AAGxB,cAAI,gBAAgB,MAAM,SAAS,GAAG,KAAK,gBAAgB,UAAU,MAAM;AAC1E,4BAAgB,QAAS,gBAAgB,MAAM,MAAM,GAAG,EAAE,IACzD,uBAAuB,CAAC;AAAA,UAC1B;AAEA,cAAI,OAAO,aAAa,WAAY,gBAA4B,SAAS,QAAQ;AAChF,kBAAM,YAAY;AAClB,uBAAW,CAAC,GAAG,KAAK,KAAK,iBAAiB,UAAU,MAAM,MAAM,GAAG;AAClE,kBAAI,MAAM,MAAM,SAAS,GAAG,KAAK,MAAM,UAAU,MAAM;AACtD,sBAAM,QAAS,MAAM,MAAM,MAAM,GAAG,EAAE,IAAI,uBAAuB,CAAC;AAAA,cACnE;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,MAAM,MAAM;AAAA,MAGZ;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAED,MAAM,8BAA8B;AACpC,MAAM,uBAAuB,MAAM;AAClC,SAAO,4BAA4B;AAAA,IAClC,KAAK,MAAM,KAAK,OAAO,IAAI,4BAA4B,MAAM;AAAA,EAC9D;AACD;AAEA,MAAM,yBAAyB,CAAC,MAAc;AAC7C,SAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,oBAAoB,EAAE,KAAK,EAAE;AAC/D;",
  "names": []
}
