@tldraw/utils 5.4.0-next.09eca5dee30d → 5.4.0-next.0ccddf5733c3

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.
@@ -1921,8 +1921,8 @@ export declare class Timers {
1921
1921
  forContext(contextId: string): {
1922
1922
  dispose: () => void;
1923
1923
  requestAnimationFrame: (callback: FrameRequestCallback) => number;
1924
- setInterval: (handler: TimerHandler, timeout?: number | undefined, ...args: any[]) => number;
1925
- setTimeout: (handler: TimerHandler, timeout?: number | undefined, ...args: any[]) => number;
1924
+ setInterval: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
1925
+ setTimeout: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
1926
1926
  };
1927
1927
  }
1928
1928
 
package/dist-cjs/index.js CHANGED
@@ -173,7 +173,7 @@ var import_version2 = require("./lib/version");
173
173
  var import_warn = require("./lib/warn");
174
174
  (0, import_version.registerTldrawLibraryVersion)(
175
175
  "@tldraw/utils",
176
- "5.4.0-next.09eca5dee30d",
176
+ "5.4.0-next.0ccddf5733c3",
177
177
  "cjs"
178
178
  );
179
179
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/id.ts"],
4
- "sourcesContent": ["/*!\n * MIT License: https://github.com/ai/nanoid/blob/main/LICENSE\n * Modified code originally from <https://github.com/ai/nanoid>\n * Copyright 2017 Andrey Sitnik <andrey@sitnik.ru>\n *\n * `nanoid` is currently only distributed as an ES module. Some tools (jest, playwright) don't\n * properly support ESM-only code yet, and tldraw itself is distributed as both an ES module and a\n * CommonJS module. By including nanoid here, we can make sure it works well in every environment\n * where tldraw is used. We can also remove some unused features like custom alphabets.\n */\n\n// all environments that tldraw runs in (browser, workers, recent node versions) have global\n// `crypto`\nconst crypto = globalThis.crypto\n\n// This alphabet uses `A-Za-z0-9_-` symbols.\n// The order of characters is optimized for better gzip and brotli compression.\n// Same as in non-secure/index.js\nconst urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n\n// It is best to make fewer, larger requests to the crypto module to\n// avoid system call overhead. So, random numbers are generated in a\n// pool. The pool is a Buffer that is larger than the initial random\n// request size by this multiplier. The pool is enlarged if subsequent\n// requests exceed the maximum buffer size.\nconst POOL_SIZE_MULTIPLIER = 128\nlet pool: Uint8Array, poolOffset: number\n\nfunction fillPool(bytes: number) {\n\tif (!pool || pool.length < bytes) {\n\t\tpool = new Uint8Array(bytes * POOL_SIZE_MULTIPLIER)\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t} else if (poolOffset + bytes > pool.length) {\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t}\n\tpoolOffset += bytes\n}\n\nfunction nanoid(size = 21) {\n\t// `-=` convert `size` to number to prevent `valueOf` abusing\n\tfillPool((size -= 0))\n\tlet id = ''\n\t// We are reading directly from the random pool to avoid creating new array\n\tfor (let i = poolOffset - size; i < poolOffset; i++) {\n\t\t// It is incorrect to use bytes exceeding the alphabet size.\n\t\t// The following mask reduces the random byte in the 0-255 value\n\t\t// range to the 0-63 value range. Therefore, adding hacks, such\n\t\t// as empty string fallback or magic numbers, is unnecessary because\n\t\t// the bitmask trims bytes down to the alphabet size.\n\t\tid += urlAlphabet[pool[i] & 63]\n\t}\n\treturn id\n}\n\nlet impl = nanoid\n/**\n * Mock the unique ID generator with a custom implementation for testing.\n *\n * Replaces the internal ID generation function with a custom one. This is useful\n * for testing scenarios where you need predictable or deterministic IDs.\n *\n * @param fn - The mock function that should return a string ID. Takes optional size parameter.\n * @example\n * ```ts\n * // Mock with predictable IDs for testing\n * mockUniqueId((size = 21) => 'test-id-' + size)\n * console.log(uniqueId()) // 'test-id-21'\n * console.log(uniqueId(10)) // 'test-id-10'\n *\n * // Restore original implementation when done\n * restoreUniqueId()\n * ```\n * @internal\n */\nexport function mockUniqueId(fn: (size?: number) => string) {\n\timpl = fn\n}\n\n/**\n * Restore the original unique ID generator after mocking.\n *\n * Resets the ID generation function back to the original nanoid implementation.\n * This should be called after testing to restore normal ID generation behavior.\n *\n * @example\n * ```ts\n * // After mocking for tests\n * mockUniqueId(() => 'mock-id')\n *\n * // Restore original behavior\n * restoreUniqueId()\n * console.log(uniqueId()) // Now generates real random IDs again\n * ```\n * @internal\n */\nexport function restoreUniqueId() {\n\timpl = nanoid\n}\n\n/**\n * Generate a unique ID using a modified nanoid algorithm.\n *\n * Generates a cryptographically secure random string ID using URL-safe characters.\n * The default size is 21 characters, which provides a good balance of uniqueness\n * and brevity. Uses the global crypto API for secure random number generation.\n *\n * @param size - Optional length of the generated ID (defaults to 21 characters)\n * @returns A unique string identifier\n * @example\n * ```ts\n * // Generate default 21-character ID\n * const id = uniqueId()\n * console.log(id) // 'V1StGXR8_Z5jdHi6B-myT'\n *\n * // Generate shorter ID\n * const shortId = uniqueId(10)\n * console.log(shortId) // 'V1StGXR8_Z'\n *\n * // Generate longer ID\n * const longId = uniqueId(32)\n * console.log(longId) // 'V1StGXR8_Z5jdHi6B-myTVKahvjdx...'\n * ```\n * @public\n */\nexport function uniqueId(size?: number): string {\n\treturn impl(size)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,SAAS,WAAW;AAK1B,MAAM,cAAc;AAOpB,MAAM,uBAAuB;AAC7B,IAAI,MAAkB;AAEtB,SAAS,SAAS,OAAe;AAChC,MAAI,CAAC,QAAQ,KAAK,SAAS,OAAO;AACjC,WAAO,IAAI,WAAW,QAAQ,oBAAoB;AAClD,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd,WAAW,aAAa,QAAQ,KAAK,QAAQ;AAC5C,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd;AACA,gBAAc;AACf;AAEA,SAAS,OAAO,OAAO,IAAI;AAE1B,WAAU,QAAQ,CAAE;AACpB,MAAI,KAAK;AAET,WAAS,IAAI,aAAa,MAAM,IAAI,YAAY,KAAK;AAMpD,UAAM,YAAY,KAAK,CAAC,IAAI,EAAE;AAAA,EAC/B;AACA,SAAO;AACR;AAEA,IAAI,OAAO;AAoBJ,SAAS,aAAa,IAA+B;AAC3D,SAAO;AACR;AAmBO,SAAS,kBAAkB;AACjC,SAAO;AACR;AA2BO,SAAS,SAAS,MAAuB;AAC/C,SAAO,KAAK,IAAI;AACjB;",
4
+ "sourcesContent": ["/*!\n * MIT License: https://github.com/ai/nanoid/blob/main/LICENSE\n * Modified code originally from <https://github.com/ai/nanoid>\n * Copyright 2017 Andrey Sitnik <andrey@sitnik.ru>\n *\n * `nanoid` is currently only distributed as an ES module. Some tools (jest, playwright) don't\n * properly support ESM-only code yet, and tldraw itself is distributed as both an ES module and a\n * CommonJS module. By including nanoid here, we can make sure it works well in every environment\n * where tldraw is used. We can also remove some unused features like custom alphabets.\n */\n\n// all environments that tldraw runs in (browser, workers, recent node versions) have global\n// `crypto`\nconst crypto = globalThis.crypto\n\n// This alphabet uses `A-Za-z0-9_-` symbols.\n// The order of characters is optimized for better gzip and brotli compression.\n// Same as in non-secure/index.js\nconst urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n\n// It is best to make fewer, larger requests to the crypto module to\n// avoid system call overhead. So, random numbers are generated in a\n// pool. The pool is a Buffer that is larger than the initial random\n// request size by this multiplier. The pool is enlarged if subsequent\n// requests exceed the maximum buffer size.\nconst POOL_SIZE_MULTIPLIER = 128\nlet pool: Uint8Array<ArrayBuffer>, poolOffset: number\n\nfunction fillPool(bytes: number) {\n\tif (!pool || pool.length < bytes) {\n\t\tpool = new Uint8Array(bytes * POOL_SIZE_MULTIPLIER)\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t} else if (poolOffset + bytes > pool.length) {\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t}\n\tpoolOffset += bytes\n}\n\nfunction nanoid(size = 21) {\n\t// `-=` convert `size` to number to prevent `valueOf` abusing\n\tfillPool((size -= 0))\n\tlet id = ''\n\t// We are reading directly from the random pool to avoid creating new array\n\tfor (let i = poolOffset - size; i < poolOffset; i++) {\n\t\t// It is incorrect to use bytes exceeding the alphabet size.\n\t\t// The following mask reduces the random byte in the 0-255 value\n\t\t// range to the 0-63 value range. Therefore, adding hacks, such\n\t\t// as empty string fallback or magic numbers, is unnecessary because\n\t\t// the bitmask trims bytes down to the alphabet size.\n\t\tid += urlAlphabet[pool[i] & 63]\n\t}\n\treturn id\n}\n\nlet impl = nanoid\n/**\n * Mock the unique ID generator with a custom implementation for testing.\n *\n * Replaces the internal ID generation function with a custom one. This is useful\n * for testing scenarios where you need predictable or deterministic IDs.\n *\n * @param fn - The mock function that should return a string ID. Takes optional size parameter.\n * @example\n * ```ts\n * // Mock with predictable IDs for testing\n * mockUniqueId((size = 21) => 'test-id-' + size)\n * console.log(uniqueId()) // 'test-id-21'\n * console.log(uniqueId(10)) // 'test-id-10'\n *\n * // Restore original implementation when done\n * restoreUniqueId()\n * ```\n * @internal\n */\nexport function mockUniqueId(fn: (size?: number) => string) {\n\timpl = fn\n}\n\n/**\n * Restore the original unique ID generator after mocking.\n *\n * Resets the ID generation function back to the original nanoid implementation.\n * This should be called after testing to restore normal ID generation behavior.\n *\n * @example\n * ```ts\n * // After mocking for tests\n * mockUniqueId(() => 'mock-id')\n *\n * // Restore original behavior\n * restoreUniqueId()\n * console.log(uniqueId()) // Now generates real random IDs again\n * ```\n * @internal\n */\nexport function restoreUniqueId() {\n\timpl = nanoid\n}\n\n/**\n * Generate a unique ID using a modified nanoid algorithm.\n *\n * Generates a cryptographically secure random string ID using URL-safe characters.\n * The default size is 21 characters, which provides a good balance of uniqueness\n * and brevity. Uses the global crypto API for secure random number generation.\n *\n * @param size - Optional length of the generated ID (defaults to 21 characters)\n * @returns A unique string identifier\n * @example\n * ```ts\n * // Generate default 21-character ID\n * const id = uniqueId()\n * console.log(id) // 'V1StGXR8_Z5jdHi6B-myT'\n *\n * // Generate shorter ID\n * const shortId = uniqueId(10)\n * console.log(shortId) // 'V1StGXR8_Z'\n *\n * // Generate longer ID\n * const longId = uniqueId(32)\n * console.log(longId) // 'V1StGXR8_Z5jdHi6B-myTVKahvjdx...'\n * ```\n * @public\n */\nexport function uniqueId(size?: number): string {\n\treturn impl(size)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,SAAS,WAAW;AAK1B,MAAM,cAAc;AAOpB,MAAM,uBAAuB;AAC7B,IAAI,MAA+B;AAEnC,SAAS,SAAS,OAAe;AAChC,MAAI,CAAC,QAAQ,KAAK,SAAS,OAAO;AACjC,WAAO,IAAI,WAAW,QAAQ,oBAAoB;AAClD,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd,WAAW,aAAa,QAAQ,KAAK,QAAQ;AAC5C,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd;AACA,gBAAc;AACf;AAEA,SAAS,OAAO,OAAO,IAAI;AAE1B,WAAU,QAAQ,CAAE;AACpB,MAAI,KAAK;AAET,WAAS,IAAI,aAAa,MAAM,IAAI,YAAY,KAAK;AAMpD,UAAM,YAAY,KAAK,CAAC,IAAI,EAAE;AAAA,EAC/B;AACA,SAAO;AACR;AAEA,IAAI,OAAO;AAoBJ,SAAS,aAAa,IAA+B;AAC3D,SAAO;AACR;AAmBO,SAAS,kBAAkB;AACjC,SAAO;AACR;AA2BO,SAAS,SAAS,MAAuB;AAC/C,SAAO,KAAK,IAAI;AACjB;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/version.ts"],
4
- "sourcesContent": ["interface TldrawLibraryVersion {\n\tname: string\n\tversion: string\n\tmodules: string\n}\n\ninterface TldrawLibraryVersionInfo {\n\tversions: TldrawLibraryVersion[]\n\tdidWarn: boolean\n\tscheduledNotice: number | NodeJS.Timeout | null\n}\n\nconst TLDRAW_LIBRARY_VERSION_KEY = '__TLDRAW_LIBRARY_VERSIONS__' as const\n\n// eslint-disable-next-line @typescript-eslint/prefer-namespace-keyword, @typescript-eslint/no-namespace, no-shadow-restricted-names\ndeclare module globalThis {\n\texport const __TLDRAW_LIBRARY_VERSIONS__: TldrawLibraryVersionInfo\n}\n\nfunction getLibraryVersions(): TldrawLibraryVersionInfo {\n\tif (globalThis[TLDRAW_LIBRARY_VERSION_KEY]) {\n\t\treturn globalThis[TLDRAW_LIBRARY_VERSION_KEY]\n\t}\n\n\tconst info: TldrawLibraryVersionInfo = {\n\t\tversions: [],\n\t\tdidWarn: false,\n\t\tscheduledNotice: null,\n\t}\n\n\tObject.defineProperty(globalThis, TLDRAW_LIBRARY_VERSION_KEY, {\n\t\tvalue: info,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t\tenumerable: false,\n\t})\n\n\treturn info\n}\n\n/**\n * Clears all registered library versions and resets warning state.\n * This function is intended for testing purposes only to reset the global version tracking state.\n * @returns void\n * @example\n * ```ts\n * // In a test setup\n * beforeEach(() => {\n * clearRegisteredVersionsForTests()\n * })\n *\n * // Now version tracking starts fresh for each test\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * ```\n * @internal\n */\nexport function clearRegisteredVersionsForTests() {\n\tconst info = getLibraryVersions()\n\tinfo.versions = []\n\tinfo.didWarn = false\n\tif (info.scheduledNotice) {\n\t\tclearTimeout(info.scheduledNotice)\n\t\tinfo.scheduledNotice = null\n\t}\n}\n\n/**\n * Registers a tldraw library version for conflict detection.\n * This function tracks different tldraw library versions to warn about potential conflicts\n * when multiple versions are loaded simultaneously.\n * @param name - The name of the tldraw library package (e.g., '\\@tldraw/editor').\n * @param version - The semantic version string (e.g., '2.0.0').\n * @param modules - The module system being used ('esm' or 'cjs').\n * @returns void\n * @example\n * ```ts\n * // Register a library version during package initialization\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * registerTldrawLibraryVersion('@tldraw/tldraw', '2.0.0', 'esm')\n *\n * // If conflicting versions are detected, warnings will be logged:\n * registerTldrawLibraryVersion('@tldraw/editor', '1.9.0', 'cjs')\n * // Console warning about version mismatch will appear\n * ```\n * @internal\n */\nexport function registerTldrawLibraryVersion(name?: string, version?: string, modules?: string) {\n\tif (!name || !version || !modules) {\n\t\tif ((globalThis as any).TLDRAW_LIBRARY_IS_BUILD) {\n\t\t\tthrow new Error('Missing name/version/module system in built version of tldraw library')\n\t\t}\n\t\treturn\n\t}\n\n\tconst info = getLibraryVersions()\n\n\t// In Next.js dev mode, Fast Refresh re-executes module-level code which causes\n\t// the same library to register multiple times, producing a false positive warning.\n\t// We skip exact duplicates only in Next.js dev to avoid hiding genuine issues.\n\tif (isNextjsDev()) {\n\t\tconst isDuplicate = info.versions.some(\n\t\t\t(v) => v.name === name && v.version === version && v.modules === modules\n\t\t)\n\t\tif (isDuplicate) return\n\t}\n\n\tinfo.versions.push({ name, version, modules })\n\n\tif (!info.scheduledNotice) {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\tinfo.scheduledNotice = setTimeout(() => {\n\t\t\t\tinfo.scheduledNotice = null\n\t\t\t\tcheckLibraryVersions(info)\n\t\t\t}, 100)\n\t\t} catch {\n\t\t\t// some environments (e.g. cloudflare workers) don't support setTimeout immediately, only in a handler.\n\t\t\t// in this case, we'll just check immediately.\n\t\t\tcheckLibraryVersions(info)\n\t\t}\n\t}\n}\n\nfunction checkLibraryVersions(info: TldrawLibraryVersionInfo) {\n\tif (!info.versions.length) return\n\tif (info.didWarn) return\n\n\tconst sorted = info.versions.sort((a, b) => compareVersions(a.version, b.version))\n\tconst latestVersion = sorted[sorted.length - 1].version\n\n\tconst matchingVersions = new Set<string>()\n\tconst nonMatchingVersions = new Map<string, Set<string>>()\n\tfor (const lib of sorted) {\n\t\tif (nonMatchingVersions.has(lib.name)) {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (lib.version === latestVersion) {\n\t\t\tmatchingVersions.add(lib.name)\n\t\t} else {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t}\n\t}\n\n\tif (nonMatchingVersions.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple versions of tldraw libraries installed. This can lead to bugs and unexpected behavior.', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t`The latest version you have installed is ${format(`v${latestVersion}`, ['bold', 'textBlue'])}. The following libraries are on the latest version:`,\n\t\t\t...Array.from(matchingVersions, (name) => ` \u2022 \u2705 ${format(name, ['bold'])}`),\n\t\t\t'',\n\t\t\t`The following libraries are not on the latest version, or have multiple versions installed:`,\n\t\t\t...Array.from(nonMatchingVersions, ([name, versions]) => {\n\t\t\t\tconst sortedVersions = Array.from(versions)\n\t\t\t\t\t.sort(compareVersions)\n\t\t\t\t\t.map((v) => format(`v${v}`, v === latestVersion ? ['textGreen'] : ['textRed']))\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} (${sortedVersions.join(', ')})`\n\t\t\t}),\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n\n\t// at this point, we know that everything has the same version. there may still be duplicates though!\n\tconst potentialDuplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const lib of sorted) {\n\t\tentry(potentialDuplicates, lib.name, { version: lib.version, modules: [] }).modules.push(\n\t\t\tlib.modules\n\t\t)\n\t}\n\n\tconst duplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const [name, lib] of potentialDuplicates) {\n\t\tif (lib.modules.length > 1) duplicates.set(name, lib)\n\t}\n\n\tif (duplicates.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple instances of some tldraw libraries active. This can lead to bugs and unexpected behavior. ', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t'This usually means that your bundler is misconfigured, and is importing the same library multiple times - usually once as an ES Module, and once as a CommonJS module.',\n\t\t\t'',\n\t\t\t'The following libraries have been imported multiple times:',\n\t\t\t...Array.from(duplicates, ([name, lib]) => {\n\t\t\t\tconst modules = lib.modules\n\t\t\t\t\t.map((m, i) => (m === 'esm' ? ` ${i + 1}. ES Modules` : ` ${i + 1}. CommonJS`))\n\t\t\t\t\t.join('\\n')\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} v${lib.version}: \\n${modules}`\n\t\t\t}),\n\t\t\t'',\n\t\t\t'You should configure your bundler to only import one version of each library.',\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n}\n\nfunction compareVersions(a: string, b: string) {\n\tconst aMatch = a.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\tconst bMatch = b.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\n\tif (!aMatch || !bMatch) return a.localeCompare(b)\n\tif (aMatch[1] !== bMatch[1]) return Number(aMatch[1]) - Number(bMatch[1])\n\tif (aMatch[2] !== bMatch[2]) return Number(aMatch[2]) - Number(bMatch[2])\n\tif (aMatch[3] !== bMatch[3]) return Number(aMatch[3]) - Number(bMatch[3])\n\tif (aMatch[4] && bMatch[4]) return aMatch[4].localeCompare(bMatch[4])\n\tif (aMatch[4]) return 1\n\tif (bMatch[4]) return -1\n\treturn 0\n}\n\nconst formats = {\n\tbold: '1',\n\ttextBlue: '94',\n\ttextRed: '31',\n\ttextGreen: '32',\n\tbgRed: '41',\n\ttextWhite: '97',\n} as const\nfunction format(value: string, formatters: (keyof typeof formats)[] = []) {\n\treturn `\\x1B[${formatters.map((f) => formats[f]).join(';')}m${value}\\x1B[m`\n}\n\nfunction isNextjsDev(): boolean {\n\ttry {\n\t\treturn process.env.NODE_ENV === 'development' && '__NEXT_DATA__' in globalThis\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction entry<K, V>(map: Map<K, V>, key: K, defaultValue: V): V {\n\tif (map.has(key)) {\n\t\treturn map.get(key)!\n\t}\n\tmap.set(key, defaultValue)\n\treturn defaultValue\n}\n"],
4
+ "sourcesContent": ["interface TldrawLibraryVersion {\n\tname: string\n\tversion: string\n\tmodules: string\n}\n\ninterface TldrawLibraryVersionInfo {\n\tversions: TldrawLibraryVersion[]\n\tdidWarn: boolean\n\tscheduledNotice: number | NodeJS.Timeout | null\n}\n\nconst TLDRAW_LIBRARY_VERSION_KEY = '__TLDRAW_LIBRARY_VERSIONS__' as const\n\n// eslint-disable-next-line @typescript-eslint/no-namespace, no-shadow-restricted-names\ndeclare namespace globalThis {\n\texport const __TLDRAW_LIBRARY_VERSIONS__: TldrawLibraryVersionInfo\n}\n\nfunction getLibraryVersions(): TldrawLibraryVersionInfo {\n\tif (globalThis[TLDRAW_LIBRARY_VERSION_KEY]) {\n\t\treturn globalThis[TLDRAW_LIBRARY_VERSION_KEY]\n\t}\n\n\tconst info: TldrawLibraryVersionInfo = {\n\t\tversions: [],\n\t\tdidWarn: false,\n\t\tscheduledNotice: null,\n\t}\n\n\tObject.defineProperty(globalThis, TLDRAW_LIBRARY_VERSION_KEY, {\n\t\tvalue: info,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t\tenumerable: false,\n\t})\n\n\treturn info\n}\n\n/**\n * Clears all registered library versions and resets warning state.\n * This function is intended for testing purposes only to reset the global version tracking state.\n * @returns void\n * @example\n * ```ts\n * // In a test setup\n * beforeEach(() => {\n * clearRegisteredVersionsForTests()\n * })\n *\n * // Now version tracking starts fresh for each test\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * ```\n * @internal\n */\nexport function clearRegisteredVersionsForTests() {\n\tconst info = getLibraryVersions()\n\tinfo.versions = []\n\tinfo.didWarn = false\n\tif (info.scheduledNotice) {\n\t\tclearTimeout(info.scheduledNotice)\n\t\tinfo.scheduledNotice = null\n\t}\n}\n\n/**\n * Registers a tldraw library version for conflict detection.\n * This function tracks different tldraw library versions to warn about potential conflicts\n * when multiple versions are loaded simultaneously.\n * @param name - The name of the tldraw library package (e.g., '\\@tldraw/editor').\n * @param version - The semantic version string (e.g., '2.0.0').\n * @param modules - The module system being used ('esm' or 'cjs').\n * @returns void\n * @example\n * ```ts\n * // Register a library version during package initialization\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * registerTldrawLibraryVersion('@tldraw/tldraw', '2.0.0', 'esm')\n *\n * // If conflicting versions are detected, warnings will be logged:\n * registerTldrawLibraryVersion('@tldraw/editor', '1.9.0', 'cjs')\n * // Console warning about version mismatch will appear\n * ```\n * @internal\n */\nexport function registerTldrawLibraryVersion(name?: string, version?: string, modules?: string) {\n\tif (!name || !version || !modules) {\n\t\tif ((globalThis as any).TLDRAW_LIBRARY_IS_BUILD) {\n\t\t\tthrow new Error('Missing name/version/module system in built version of tldraw library')\n\t\t}\n\t\treturn\n\t}\n\n\tconst info = getLibraryVersions()\n\n\t// In Next.js dev mode, Fast Refresh re-executes module-level code which causes\n\t// the same library to register multiple times, producing a false positive warning.\n\t// We skip exact duplicates only in Next.js dev to avoid hiding genuine issues.\n\tif (isNextjsDev()) {\n\t\tconst isDuplicate = info.versions.some(\n\t\t\t(v) => v.name === name && v.version === version && v.modules === modules\n\t\t)\n\t\tif (isDuplicate) return\n\t}\n\n\tinfo.versions.push({ name, version, modules })\n\n\tif (!info.scheduledNotice) {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\tinfo.scheduledNotice = setTimeout(() => {\n\t\t\t\tinfo.scheduledNotice = null\n\t\t\t\tcheckLibraryVersions(info)\n\t\t\t}, 100)\n\t\t} catch {\n\t\t\t// some environments (e.g. cloudflare workers) don't support setTimeout immediately, only in a handler.\n\t\t\t// in this case, we'll just check immediately.\n\t\t\tcheckLibraryVersions(info)\n\t\t}\n\t}\n}\n\nfunction checkLibraryVersions(info: TldrawLibraryVersionInfo) {\n\tif (!info.versions.length) return\n\tif (info.didWarn) return\n\n\tconst sorted = info.versions.sort((a, b) => compareVersions(a.version, b.version))\n\tconst latestVersion = sorted[sorted.length - 1].version\n\n\tconst matchingVersions = new Set<string>()\n\tconst nonMatchingVersions = new Map<string, Set<string>>()\n\tfor (const lib of sorted) {\n\t\tif (nonMatchingVersions.has(lib.name)) {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (lib.version === latestVersion) {\n\t\t\tmatchingVersions.add(lib.name)\n\t\t} else {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t}\n\t}\n\n\tif (nonMatchingVersions.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple versions of tldraw libraries installed. This can lead to bugs and unexpected behavior.', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t`The latest version you have installed is ${format(`v${latestVersion}`, ['bold', 'textBlue'])}. The following libraries are on the latest version:`,\n\t\t\t...Array.from(matchingVersions, (name) => ` \u2022 \u2705 ${format(name, ['bold'])}`),\n\t\t\t'',\n\t\t\t`The following libraries are not on the latest version, or have multiple versions installed:`,\n\t\t\t...Array.from(nonMatchingVersions, ([name, versions]) => {\n\t\t\t\tconst sortedVersions = Array.from(versions)\n\t\t\t\t\t.sort(compareVersions)\n\t\t\t\t\t.map((v) => format(`v${v}`, v === latestVersion ? ['textGreen'] : ['textRed']))\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} (${sortedVersions.join(', ')})`\n\t\t\t}),\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n\n\t// at this point, we know that everything has the same version. there may still be duplicates though!\n\tconst potentialDuplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const lib of sorted) {\n\t\tentry(potentialDuplicates, lib.name, { version: lib.version, modules: [] }).modules.push(\n\t\t\tlib.modules\n\t\t)\n\t}\n\n\tconst duplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const [name, lib] of potentialDuplicates) {\n\t\tif (lib.modules.length > 1) duplicates.set(name, lib)\n\t}\n\n\tif (duplicates.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple instances of some tldraw libraries active. This can lead to bugs and unexpected behavior. ', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t'This usually means that your bundler is misconfigured, and is importing the same library multiple times - usually once as an ES Module, and once as a CommonJS module.',\n\t\t\t'',\n\t\t\t'The following libraries have been imported multiple times:',\n\t\t\t...Array.from(duplicates, ([name, lib]) => {\n\t\t\t\tconst modules = lib.modules\n\t\t\t\t\t.map((m, i) => (m === 'esm' ? ` ${i + 1}. ES Modules` : ` ${i + 1}. CommonJS`))\n\t\t\t\t\t.join('\\n')\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} v${lib.version}: \\n${modules}`\n\t\t\t}),\n\t\t\t'',\n\t\t\t'You should configure your bundler to only import one version of each library.',\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n}\n\nfunction compareVersions(a: string, b: string) {\n\tconst aMatch = a.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\tconst bMatch = b.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\n\tif (!aMatch || !bMatch) return a.localeCompare(b)\n\tif (aMatch[1] !== bMatch[1]) return Number(aMatch[1]) - Number(bMatch[1])\n\tif (aMatch[2] !== bMatch[2]) return Number(aMatch[2]) - Number(bMatch[2])\n\tif (aMatch[3] !== bMatch[3]) return Number(aMatch[3]) - Number(bMatch[3])\n\tif (aMatch[4] && bMatch[4]) return aMatch[4].localeCompare(bMatch[4])\n\tif (aMatch[4]) return 1\n\tif (bMatch[4]) return -1\n\treturn 0\n}\n\nconst formats = {\n\tbold: '1',\n\ttextBlue: '94',\n\ttextRed: '31',\n\ttextGreen: '32',\n\tbgRed: '41',\n\ttextWhite: '97',\n} as const\nfunction format(value: string, formatters: (keyof typeof formats)[] = []) {\n\treturn `\\x1B[${formatters.map((f) => formats[f]).join(';')}m${value}\\x1B[m`\n}\n\nfunction isNextjsDev(): boolean {\n\ttry {\n\t\treturn process.env.NODE_ENV === 'development' && '__NEXT_DATA__' in globalThis\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction entry<K, V>(map: Map<K, V>, key: K, defaultValue: V): V {\n\tif (map.has(key)) {\n\t\treturn map.get(key)!\n\t}\n\tmap.set(key, defaultValue)\n\treturn defaultValue\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1921,8 +1921,8 @@ export declare class Timers {
1921
1921
  forContext(contextId: string): {
1922
1922
  dispose: () => void;
1923
1923
  requestAnimationFrame: (callback: FrameRequestCallback) => number;
1924
- setInterval: (handler: TimerHandler, timeout?: number | undefined, ...args: any[]) => number;
1925
- setTimeout: (handler: TimerHandler, timeout?: number | undefined, ...args: any[]) => number;
1924
+ setInterval: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
1925
+ setTimeout: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
1926
1926
  };
1927
1927
  }
1928
1928
 
@@ -103,7 +103,7 @@ import { registerTldrawLibraryVersion as registerTldrawLibraryVersion2 } from ".
103
103
  import { warnDeprecatedGetter, warnOnce } from "./lib/warn.mjs";
104
104
  registerTldrawLibraryVersion(
105
105
  "@tldraw/utils",
106
- "5.4.0-next.09eca5dee30d",
106
+ "5.4.0-next.0ccddf5733c3",
107
107
  "esm"
108
108
  );
109
109
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/id.ts"],
4
- "sourcesContent": ["/*!\n * MIT License: https://github.com/ai/nanoid/blob/main/LICENSE\n * Modified code originally from <https://github.com/ai/nanoid>\n * Copyright 2017 Andrey Sitnik <andrey@sitnik.ru>\n *\n * `nanoid` is currently only distributed as an ES module. Some tools (jest, playwright) don't\n * properly support ESM-only code yet, and tldraw itself is distributed as both an ES module and a\n * CommonJS module. By including nanoid here, we can make sure it works well in every environment\n * where tldraw is used. We can also remove some unused features like custom alphabets.\n */\n\n// all environments that tldraw runs in (browser, workers, recent node versions) have global\n// `crypto`\nconst crypto = globalThis.crypto\n\n// This alphabet uses `A-Za-z0-9_-` symbols.\n// The order of characters is optimized for better gzip and brotli compression.\n// Same as in non-secure/index.js\nconst urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n\n// It is best to make fewer, larger requests to the crypto module to\n// avoid system call overhead. So, random numbers are generated in a\n// pool. The pool is a Buffer that is larger than the initial random\n// request size by this multiplier. The pool is enlarged if subsequent\n// requests exceed the maximum buffer size.\nconst POOL_SIZE_MULTIPLIER = 128\nlet pool: Uint8Array, poolOffset: number\n\nfunction fillPool(bytes: number) {\n\tif (!pool || pool.length < bytes) {\n\t\tpool = new Uint8Array(bytes * POOL_SIZE_MULTIPLIER)\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t} else if (poolOffset + bytes > pool.length) {\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t}\n\tpoolOffset += bytes\n}\n\nfunction nanoid(size = 21) {\n\t// `-=` convert `size` to number to prevent `valueOf` abusing\n\tfillPool((size -= 0))\n\tlet id = ''\n\t// We are reading directly from the random pool to avoid creating new array\n\tfor (let i = poolOffset - size; i < poolOffset; i++) {\n\t\t// It is incorrect to use bytes exceeding the alphabet size.\n\t\t// The following mask reduces the random byte in the 0-255 value\n\t\t// range to the 0-63 value range. Therefore, adding hacks, such\n\t\t// as empty string fallback or magic numbers, is unnecessary because\n\t\t// the bitmask trims bytes down to the alphabet size.\n\t\tid += urlAlphabet[pool[i] & 63]\n\t}\n\treturn id\n}\n\nlet impl = nanoid\n/**\n * Mock the unique ID generator with a custom implementation for testing.\n *\n * Replaces the internal ID generation function with a custom one. This is useful\n * for testing scenarios where you need predictable or deterministic IDs.\n *\n * @param fn - The mock function that should return a string ID. Takes optional size parameter.\n * @example\n * ```ts\n * // Mock with predictable IDs for testing\n * mockUniqueId((size = 21) => 'test-id-' + size)\n * console.log(uniqueId()) // 'test-id-21'\n * console.log(uniqueId(10)) // 'test-id-10'\n *\n * // Restore original implementation when done\n * restoreUniqueId()\n * ```\n * @internal\n */\nexport function mockUniqueId(fn: (size?: number) => string) {\n\timpl = fn\n}\n\n/**\n * Restore the original unique ID generator after mocking.\n *\n * Resets the ID generation function back to the original nanoid implementation.\n * This should be called after testing to restore normal ID generation behavior.\n *\n * @example\n * ```ts\n * // After mocking for tests\n * mockUniqueId(() => 'mock-id')\n *\n * // Restore original behavior\n * restoreUniqueId()\n * console.log(uniqueId()) // Now generates real random IDs again\n * ```\n * @internal\n */\nexport function restoreUniqueId() {\n\timpl = nanoid\n}\n\n/**\n * Generate a unique ID using a modified nanoid algorithm.\n *\n * Generates a cryptographically secure random string ID using URL-safe characters.\n * The default size is 21 characters, which provides a good balance of uniqueness\n * and brevity. Uses the global crypto API for secure random number generation.\n *\n * @param size - Optional length of the generated ID (defaults to 21 characters)\n * @returns A unique string identifier\n * @example\n * ```ts\n * // Generate default 21-character ID\n * const id = uniqueId()\n * console.log(id) // 'V1StGXR8_Z5jdHi6B-myT'\n *\n * // Generate shorter ID\n * const shortId = uniqueId(10)\n * console.log(shortId) // 'V1StGXR8_Z'\n *\n * // Generate longer ID\n * const longId = uniqueId(32)\n * console.log(longId) // 'V1StGXR8_Z5jdHi6B-myTVKahvjdx...'\n * ```\n * @public\n */\nexport function uniqueId(size?: number): string {\n\treturn impl(size)\n}\n"],
5
- "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,SAAS,WAAW;AAK1B,MAAM,cAAc;AAOpB,MAAM,uBAAuB;AAC7B,IAAI,MAAkB;AAEtB,SAAS,SAAS,OAAe;AAChC,MAAI,CAAC,QAAQ,KAAK,SAAS,OAAO;AACjC,WAAO,IAAI,WAAW,QAAQ,oBAAoB;AAClD,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd,WAAW,aAAa,QAAQ,KAAK,QAAQ;AAC5C,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd;AACA,gBAAc;AACf;AAEA,SAAS,OAAO,OAAO,IAAI;AAE1B,WAAU,QAAQ,CAAE;AACpB,MAAI,KAAK;AAET,WAAS,IAAI,aAAa,MAAM,IAAI,YAAY,KAAK;AAMpD,UAAM,YAAY,KAAK,CAAC,IAAI,EAAE;AAAA,EAC/B;AACA,SAAO;AACR;AAEA,IAAI,OAAO;AAoBJ,SAAS,aAAa,IAA+B;AAC3D,SAAO;AACR;AAmBO,SAAS,kBAAkB;AACjC,SAAO;AACR;AA2BO,SAAS,SAAS,MAAuB;AAC/C,SAAO,KAAK,IAAI;AACjB;",
4
+ "sourcesContent": ["/*!\n * MIT License: https://github.com/ai/nanoid/blob/main/LICENSE\n * Modified code originally from <https://github.com/ai/nanoid>\n * Copyright 2017 Andrey Sitnik <andrey@sitnik.ru>\n *\n * `nanoid` is currently only distributed as an ES module. Some tools (jest, playwright) don't\n * properly support ESM-only code yet, and tldraw itself is distributed as both an ES module and a\n * CommonJS module. By including nanoid here, we can make sure it works well in every environment\n * where tldraw is used. We can also remove some unused features like custom alphabets.\n */\n\n// all environments that tldraw runs in (browser, workers, recent node versions) have global\n// `crypto`\nconst crypto = globalThis.crypto\n\n// This alphabet uses `A-Za-z0-9_-` symbols.\n// The order of characters is optimized for better gzip and brotli compression.\n// Same as in non-secure/index.js\nconst urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n\n// It is best to make fewer, larger requests to the crypto module to\n// avoid system call overhead. So, random numbers are generated in a\n// pool. The pool is a Buffer that is larger than the initial random\n// request size by this multiplier. The pool is enlarged if subsequent\n// requests exceed the maximum buffer size.\nconst POOL_SIZE_MULTIPLIER = 128\nlet pool: Uint8Array<ArrayBuffer>, poolOffset: number\n\nfunction fillPool(bytes: number) {\n\tif (!pool || pool.length < bytes) {\n\t\tpool = new Uint8Array(bytes * POOL_SIZE_MULTIPLIER)\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t} else if (poolOffset + bytes > pool.length) {\n\t\tcrypto.getRandomValues(pool)\n\t\tpoolOffset = 0\n\t}\n\tpoolOffset += bytes\n}\n\nfunction nanoid(size = 21) {\n\t// `-=` convert `size` to number to prevent `valueOf` abusing\n\tfillPool((size -= 0))\n\tlet id = ''\n\t// We are reading directly from the random pool to avoid creating new array\n\tfor (let i = poolOffset - size; i < poolOffset; i++) {\n\t\t// It is incorrect to use bytes exceeding the alphabet size.\n\t\t// The following mask reduces the random byte in the 0-255 value\n\t\t// range to the 0-63 value range. Therefore, adding hacks, such\n\t\t// as empty string fallback or magic numbers, is unnecessary because\n\t\t// the bitmask trims bytes down to the alphabet size.\n\t\tid += urlAlphabet[pool[i] & 63]\n\t}\n\treturn id\n}\n\nlet impl = nanoid\n/**\n * Mock the unique ID generator with a custom implementation for testing.\n *\n * Replaces the internal ID generation function with a custom one. This is useful\n * for testing scenarios where you need predictable or deterministic IDs.\n *\n * @param fn - The mock function that should return a string ID. Takes optional size parameter.\n * @example\n * ```ts\n * // Mock with predictable IDs for testing\n * mockUniqueId((size = 21) => 'test-id-' + size)\n * console.log(uniqueId()) // 'test-id-21'\n * console.log(uniqueId(10)) // 'test-id-10'\n *\n * // Restore original implementation when done\n * restoreUniqueId()\n * ```\n * @internal\n */\nexport function mockUniqueId(fn: (size?: number) => string) {\n\timpl = fn\n}\n\n/**\n * Restore the original unique ID generator after mocking.\n *\n * Resets the ID generation function back to the original nanoid implementation.\n * This should be called after testing to restore normal ID generation behavior.\n *\n * @example\n * ```ts\n * // After mocking for tests\n * mockUniqueId(() => 'mock-id')\n *\n * // Restore original behavior\n * restoreUniqueId()\n * console.log(uniqueId()) // Now generates real random IDs again\n * ```\n * @internal\n */\nexport function restoreUniqueId() {\n\timpl = nanoid\n}\n\n/**\n * Generate a unique ID using a modified nanoid algorithm.\n *\n * Generates a cryptographically secure random string ID using URL-safe characters.\n * The default size is 21 characters, which provides a good balance of uniqueness\n * and brevity. Uses the global crypto API for secure random number generation.\n *\n * @param size - Optional length of the generated ID (defaults to 21 characters)\n * @returns A unique string identifier\n * @example\n * ```ts\n * // Generate default 21-character ID\n * const id = uniqueId()\n * console.log(id) // 'V1StGXR8_Z5jdHi6B-myT'\n *\n * // Generate shorter ID\n * const shortId = uniqueId(10)\n * console.log(shortId) // 'V1StGXR8_Z'\n *\n * // Generate longer ID\n * const longId = uniqueId(32)\n * console.log(longId) // 'V1StGXR8_Z5jdHi6B-myTVKahvjdx...'\n * ```\n * @public\n */\nexport function uniqueId(size?: number): string {\n\treturn impl(size)\n}\n"],
5
+ "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,SAAS,WAAW;AAK1B,MAAM,cAAc;AAOpB,MAAM,uBAAuB;AAC7B,IAAI,MAA+B;AAEnC,SAAS,SAAS,OAAe;AAChC,MAAI,CAAC,QAAQ,KAAK,SAAS,OAAO;AACjC,WAAO,IAAI,WAAW,QAAQ,oBAAoB;AAClD,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd,WAAW,aAAa,QAAQ,KAAK,QAAQ;AAC5C,WAAO,gBAAgB,IAAI;AAC3B,iBAAa;AAAA,EACd;AACA,gBAAc;AACf;AAEA,SAAS,OAAO,OAAO,IAAI;AAE1B,WAAU,QAAQ,CAAE;AACpB,MAAI,KAAK;AAET,WAAS,IAAI,aAAa,MAAM,IAAI,YAAY,KAAK;AAMpD,UAAM,YAAY,KAAK,CAAC,IAAI,EAAE;AAAA,EAC/B;AACA,SAAO;AACR;AAEA,IAAI,OAAO;AAoBJ,SAAS,aAAa,IAA+B;AAC3D,SAAO;AACR;AAmBO,SAAS,kBAAkB;AACjC,SAAO;AACR;AA2BO,SAAS,SAAS,MAAuB;AAC/C,SAAO,KAAK,IAAI;AACjB;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/version.ts"],
4
- "sourcesContent": ["interface TldrawLibraryVersion {\n\tname: string\n\tversion: string\n\tmodules: string\n}\n\ninterface TldrawLibraryVersionInfo {\n\tversions: TldrawLibraryVersion[]\n\tdidWarn: boolean\n\tscheduledNotice: number | NodeJS.Timeout | null\n}\n\nconst TLDRAW_LIBRARY_VERSION_KEY = '__TLDRAW_LIBRARY_VERSIONS__' as const\n\n// eslint-disable-next-line @typescript-eslint/prefer-namespace-keyword, @typescript-eslint/no-namespace, no-shadow-restricted-names\ndeclare module globalThis {\n\texport const __TLDRAW_LIBRARY_VERSIONS__: TldrawLibraryVersionInfo\n}\n\nfunction getLibraryVersions(): TldrawLibraryVersionInfo {\n\tif (globalThis[TLDRAW_LIBRARY_VERSION_KEY]) {\n\t\treturn globalThis[TLDRAW_LIBRARY_VERSION_KEY]\n\t}\n\n\tconst info: TldrawLibraryVersionInfo = {\n\t\tversions: [],\n\t\tdidWarn: false,\n\t\tscheduledNotice: null,\n\t}\n\n\tObject.defineProperty(globalThis, TLDRAW_LIBRARY_VERSION_KEY, {\n\t\tvalue: info,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t\tenumerable: false,\n\t})\n\n\treturn info\n}\n\n/**\n * Clears all registered library versions and resets warning state.\n * This function is intended for testing purposes only to reset the global version tracking state.\n * @returns void\n * @example\n * ```ts\n * // In a test setup\n * beforeEach(() => {\n * clearRegisteredVersionsForTests()\n * })\n *\n * // Now version tracking starts fresh for each test\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * ```\n * @internal\n */\nexport function clearRegisteredVersionsForTests() {\n\tconst info = getLibraryVersions()\n\tinfo.versions = []\n\tinfo.didWarn = false\n\tif (info.scheduledNotice) {\n\t\tclearTimeout(info.scheduledNotice)\n\t\tinfo.scheduledNotice = null\n\t}\n}\n\n/**\n * Registers a tldraw library version for conflict detection.\n * This function tracks different tldraw library versions to warn about potential conflicts\n * when multiple versions are loaded simultaneously.\n * @param name - The name of the tldraw library package (e.g., '\\@tldraw/editor').\n * @param version - The semantic version string (e.g., '2.0.0').\n * @param modules - The module system being used ('esm' or 'cjs').\n * @returns void\n * @example\n * ```ts\n * // Register a library version during package initialization\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * registerTldrawLibraryVersion('@tldraw/tldraw', '2.0.0', 'esm')\n *\n * // If conflicting versions are detected, warnings will be logged:\n * registerTldrawLibraryVersion('@tldraw/editor', '1.9.0', 'cjs')\n * // Console warning about version mismatch will appear\n * ```\n * @internal\n */\nexport function registerTldrawLibraryVersion(name?: string, version?: string, modules?: string) {\n\tif (!name || !version || !modules) {\n\t\tif ((globalThis as any).TLDRAW_LIBRARY_IS_BUILD) {\n\t\t\tthrow new Error('Missing name/version/module system in built version of tldraw library')\n\t\t}\n\t\treturn\n\t}\n\n\tconst info = getLibraryVersions()\n\n\t// In Next.js dev mode, Fast Refresh re-executes module-level code which causes\n\t// the same library to register multiple times, producing a false positive warning.\n\t// We skip exact duplicates only in Next.js dev to avoid hiding genuine issues.\n\tif (isNextjsDev()) {\n\t\tconst isDuplicate = info.versions.some(\n\t\t\t(v) => v.name === name && v.version === version && v.modules === modules\n\t\t)\n\t\tif (isDuplicate) return\n\t}\n\n\tinfo.versions.push({ name, version, modules })\n\n\tif (!info.scheduledNotice) {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\tinfo.scheduledNotice = setTimeout(() => {\n\t\t\t\tinfo.scheduledNotice = null\n\t\t\t\tcheckLibraryVersions(info)\n\t\t\t}, 100)\n\t\t} catch {\n\t\t\t// some environments (e.g. cloudflare workers) don't support setTimeout immediately, only in a handler.\n\t\t\t// in this case, we'll just check immediately.\n\t\t\tcheckLibraryVersions(info)\n\t\t}\n\t}\n}\n\nfunction checkLibraryVersions(info: TldrawLibraryVersionInfo) {\n\tif (!info.versions.length) return\n\tif (info.didWarn) return\n\n\tconst sorted = info.versions.sort((a, b) => compareVersions(a.version, b.version))\n\tconst latestVersion = sorted[sorted.length - 1].version\n\n\tconst matchingVersions = new Set<string>()\n\tconst nonMatchingVersions = new Map<string, Set<string>>()\n\tfor (const lib of sorted) {\n\t\tif (nonMatchingVersions.has(lib.name)) {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (lib.version === latestVersion) {\n\t\t\tmatchingVersions.add(lib.name)\n\t\t} else {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t}\n\t}\n\n\tif (nonMatchingVersions.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple versions of tldraw libraries installed. This can lead to bugs and unexpected behavior.', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t`The latest version you have installed is ${format(`v${latestVersion}`, ['bold', 'textBlue'])}. The following libraries are on the latest version:`,\n\t\t\t...Array.from(matchingVersions, (name) => ` \u2022 \u2705 ${format(name, ['bold'])}`),\n\t\t\t'',\n\t\t\t`The following libraries are not on the latest version, or have multiple versions installed:`,\n\t\t\t...Array.from(nonMatchingVersions, ([name, versions]) => {\n\t\t\t\tconst sortedVersions = Array.from(versions)\n\t\t\t\t\t.sort(compareVersions)\n\t\t\t\t\t.map((v) => format(`v${v}`, v === latestVersion ? ['textGreen'] : ['textRed']))\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} (${sortedVersions.join(', ')})`\n\t\t\t}),\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n\n\t// at this point, we know that everything has the same version. there may still be duplicates though!\n\tconst potentialDuplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const lib of sorted) {\n\t\tentry(potentialDuplicates, lib.name, { version: lib.version, modules: [] }).modules.push(\n\t\t\tlib.modules\n\t\t)\n\t}\n\n\tconst duplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const [name, lib] of potentialDuplicates) {\n\t\tif (lib.modules.length > 1) duplicates.set(name, lib)\n\t}\n\n\tif (duplicates.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple instances of some tldraw libraries active. This can lead to bugs and unexpected behavior. ', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t'This usually means that your bundler is misconfigured, and is importing the same library multiple times - usually once as an ES Module, and once as a CommonJS module.',\n\t\t\t'',\n\t\t\t'The following libraries have been imported multiple times:',\n\t\t\t...Array.from(duplicates, ([name, lib]) => {\n\t\t\t\tconst modules = lib.modules\n\t\t\t\t\t.map((m, i) => (m === 'esm' ? ` ${i + 1}. ES Modules` : ` ${i + 1}. CommonJS`))\n\t\t\t\t\t.join('\\n')\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} v${lib.version}: \\n${modules}`\n\t\t\t}),\n\t\t\t'',\n\t\t\t'You should configure your bundler to only import one version of each library.',\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n}\n\nfunction compareVersions(a: string, b: string) {\n\tconst aMatch = a.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\tconst bMatch = b.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\n\tif (!aMatch || !bMatch) return a.localeCompare(b)\n\tif (aMatch[1] !== bMatch[1]) return Number(aMatch[1]) - Number(bMatch[1])\n\tif (aMatch[2] !== bMatch[2]) return Number(aMatch[2]) - Number(bMatch[2])\n\tif (aMatch[3] !== bMatch[3]) return Number(aMatch[3]) - Number(bMatch[3])\n\tif (aMatch[4] && bMatch[4]) return aMatch[4].localeCompare(bMatch[4])\n\tif (aMatch[4]) return 1\n\tif (bMatch[4]) return -1\n\treturn 0\n}\n\nconst formats = {\n\tbold: '1',\n\ttextBlue: '94',\n\ttextRed: '31',\n\ttextGreen: '32',\n\tbgRed: '41',\n\ttextWhite: '97',\n} as const\nfunction format(value: string, formatters: (keyof typeof formats)[] = []) {\n\treturn `\\x1B[${formatters.map((f) => formats[f]).join(';')}m${value}\\x1B[m`\n}\n\nfunction isNextjsDev(): boolean {\n\ttry {\n\t\treturn process.env.NODE_ENV === 'development' && '__NEXT_DATA__' in globalThis\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction entry<K, V>(map: Map<K, V>, key: K, defaultValue: V): V {\n\tif (map.has(key)) {\n\t\treturn map.get(key)!\n\t}\n\tmap.set(key, defaultValue)\n\treturn defaultValue\n}\n"],
4
+ "sourcesContent": ["interface TldrawLibraryVersion {\n\tname: string\n\tversion: string\n\tmodules: string\n}\n\ninterface TldrawLibraryVersionInfo {\n\tversions: TldrawLibraryVersion[]\n\tdidWarn: boolean\n\tscheduledNotice: number | NodeJS.Timeout | null\n}\n\nconst TLDRAW_LIBRARY_VERSION_KEY = '__TLDRAW_LIBRARY_VERSIONS__' as const\n\n// eslint-disable-next-line @typescript-eslint/no-namespace, no-shadow-restricted-names\ndeclare namespace globalThis {\n\texport const __TLDRAW_LIBRARY_VERSIONS__: TldrawLibraryVersionInfo\n}\n\nfunction getLibraryVersions(): TldrawLibraryVersionInfo {\n\tif (globalThis[TLDRAW_LIBRARY_VERSION_KEY]) {\n\t\treturn globalThis[TLDRAW_LIBRARY_VERSION_KEY]\n\t}\n\n\tconst info: TldrawLibraryVersionInfo = {\n\t\tversions: [],\n\t\tdidWarn: false,\n\t\tscheduledNotice: null,\n\t}\n\n\tObject.defineProperty(globalThis, TLDRAW_LIBRARY_VERSION_KEY, {\n\t\tvalue: info,\n\t\twritable: false,\n\t\tconfigurable: false,\n\t\tenumerable: false,\n\t})\n\n\treturn info\n}\n\n/**\n * Clears all registered library versions and resets warning state.\n * This function is intended for testing purposes only to reset the global version tracking state.\n * @returns void\n * @example\n * ```ts\n * // In a test setup\n * beforeEach(() => {\n * clearRegisteredVersionsForTests()\n * })\n *\n * // Now version tracking starts fresh for each test\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * ```\n * @internal\n */\nexport function clearRegisteredVersionsForTests() {\n\tconst info = getLibraryVersions()\n\tinfo.versions = []\n\tinfo.didWarn = false\n\tif (info.scheduledNotice) {\n\t\tclearTimeout(info.scheduledNotice)\n\t\tinfo.scheduledNotice = null\n\t}\n}\n\n/**\n * Registers a tldraw library version for conflict detection.\n * This function tracks different tldraw library versions to warn about potential conflicts\n * when multiple versions are loaded simultaneously.\n * @param name - The name of the tldraw library package (e.g., '\\@tldraw/editor').\n * @param version - The semantic version string (e.g., '2.0.0').\n * @param modules - The module system being used ('esm' or 'cjs').\n * @returns void\n * @example\n * ```ts\n * // Register a library version during package initialization\n * registerTldrawLibraryVersion('@tldraw/editor', '2.0.0', 'esm')\n * registerTldrawLibraryVersion('@tldraw/tldraw', '2.0.0', 'esm')\n *\n * // If conflicting versions are detected, warnings will be logged:\n * registerTldrawLibraryVersion('@tldraw/editor', '1.9.0', 'cjs')\n * // Console warning about version mismatch will appear\n * ```\n * @internal\n */\nexport function registerTldrawLibraryVersion(name?: string, version?: string, modules?: string) {\n\tif (!name || !version || !modules) {\n\t\tif ((globalThis as any).TLDRAW_LIBRARY_IS_BUILD) {\n\t\t\tthrow new Error('Missing name/version/module system in built version of tldraw library')\n\t\t}\n\t\treturn\n\t}\n\n\tconst info = getLibraryVersions()\n\n\t// In Next.js dev mode, Fast Refresh re-executes module-level code which causes\n\t// the same library to register multiple times, producing a false positive warning.\n\t// We skip exact duplicates only in Next.js dev to avoid hiding genuine issues.\n\tif (isNextjsDev()) {\n\t\tconst isDuplicate = info.versions.some(\n\t\t\t(v) => v.name === name && v.version === version && v.modules === modules\n\t\t)\n\t\tif (isDuplicate) return\n\t}\n\n\tinfo.versions.push({ name, version, modules })\n\n\tif (!info.scheduledNotice) {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\tinfo.scheduledNotice = setTimeout(() => {\n\t\t\t\tinfo.scheduledNotice = null\n\t\t\t\tcheckLibraryVersions(info)\n\t\t\t}, 100)\n\t\t} catch {\n\t\t\t// some environments (e.g. cloudflare workers) don't support setTimeout immediately, only in a handler.\n\t\t\t// in this case, we'll just check immediately.\n\t\t\tcheckLibraryVersions(info)\n\t\t}\n\t}\n}\n\nfunction checkLibraryVersions(info: TldrawLibraryVersionInfo) {\n\tif (!info.versions.length) return\n\tif (info.didWarn) return\n\n\tconst sorted = info.versions.sort((a, b) => compareVersions(a.version, b.version))\n\tconst latestVersion = sorted[sorted.length - 1].version\n\n\tconst matchingVersions = new Set<string>()\n\tconst nonMatchingVersions = new Map<string, Set<string>>()\n\tfor (const lib of sorted) {\n\t\tif (nonMatchingVersions.has(lib.name)) {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (lib.version === latestVersion) {\n\t\t\tmatchingVersions.add(lib.name)\n\t\t} else {\n\t\t\tmatchingVersions.delete(lib.name)\n\t\t\tentry(nonMatchingVersions, lib.name, new Set()).add(lib.version)\n\t\t}\n\t}\n\n\tif (nonMatchingVersions.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple versions of tldraw libraries installed. This can lead to bugs and unexpected behavior.', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t`The latest version you have installed is ${format(`v${latestVersion}`, ['bold', 'textBlue'])}. The following libraries are on the latest version:`,\n\t\t\t...Array.from(matchingVersions, (name) => ` \u2022 \u2705 ${format(name, ['bold'])}`),\n\t\t\t'',\n\t\t\t`The following libraries are not on the latest version, or have multiple versions installed:`,\n\t\t\t...Array.from(nonMatchingVersions, ([name, versions]) => {\n\t\t\t\tconst sortedVersions = Array.from(versions)\n\t\t\t\t\t.sort(compareVersions)\n\t\t\t\t\t.map((v) => format(`v${v}`, v === latestVersion ? ['textGreen'] : ['textRed']))\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} (${sortedVersions.join(', ')})`\n\t\t\t}),\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n\n\t// at this point, we know that everything has the same version. there may still be duplicates though!\n\tconst potentialDuplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const lib of sorted) {\n\t\tentry(potentialDuplicates, lib.name, { version: lib.version, modules: [] }).modules.push(\n\t\t\tlib.modules\n\t\t)\n\t}\n\n\tconst duplicates = new Map<string, { version: string; modules: string[] }>()\n\tfor (const [name, lib] of potentialDuplicates) {\n\t\tif (lib.modules.length > 1) duplicates.set(name, lib)\n\t}\n\n\tif (duplicates.size > 0) {\n\t\tconst message = [\n\t\t\t`${format('[tldraw]', ['bold', 'bgRed', 'textWhite'])} ${format('You have multiple instances of some tldraw libraries active. This can lead to bugs and unexpected behavior. ', ['textRed', 'bold'])}`,\n\t\t\t'',\n\t\t\t'This usually means that your bundler is misconfigured, and is importing the same library multiple times - usually once as an ES Module, and once as a CommonJS module.',\n\t\t\t'',\n\t\t\t'The following libraries have been imported multiple times:',\n\t\t\t...Array.from(duplicates, ([name, lib]) => {\n\t\t\t\tconst modules = lib.modules\n\t\t\t\t\t.map((m, i) => (m === 'esm' ? ` ${i + 1}. ES Modules` : ` ${i + 1}. CommonJS`))\n\t\t\t\t\t.join('\\n')\n\t\t\t\treturn ` \u2022 \u274C ${format(name, ['bold'])} v${lib.version}: \\n${modules}`\n\t\t\t}),\n\t\t\t'',\n\t\t\t'You should configure your bundler to only import one version of each library.',\n\t\t]\n\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(message.join('\\n'))\n\t\tinfo.didWarn = true\n\t\treturn\n\t}\n}\n\nfunction compareVersions(a: string, b: string) {\n\tconst aMatch = a.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\tconst bMatch = b.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\w+))?$/)\n\n\tif (!aMatch || !bMatch) return a.localeCompare(b)\n\tif (aMatch[1] !== bMatch[1]) return Number(aMatch[1]) - Number(bMatch[1])\n\tif (aMatch[2] !== bMatch[2]) return Number(aMatch[2]) - Number(bMatch[2])\n\tif (aMatch[3] !== bMatch[3]) return Number(aMatch[3]) - Number(bMatch[3])\n\tif (aMatch[4] && bMatch[4]) return aMatch[4].localeCompare(bMatch[4])\n\tif (aMatch[4]) return 1\n\tif (bMatch[4]) return -1\n\treturn 0\n}\n\nconst formats = {\n\tbold: '1',\n\ttextBlue: '94',\n\ttextRed: '31',\n\ttextGreen: '32',\n\tbgRed: '41',\n\ttextWhite: '97',\n} as const\nfunction format(value: string, formatters: (keyof typeof formats)[] = []) {\n\treturn `\\x1B[${formatters.map((f) => formats[f]).join(';')}m${value}\\x1B[m`\n}\n\nfunction isNextjsDev(): boolean {\n\ttry {\n\t\treturn process.env.NODE_ENV === 'development' && '__NEXT_DATA__' in globalThis\n\t} catch {\n\t\treturn false\n\t}\n}\n\nfunction entry<K, V>(map: Map<K, V>, key: K, defaultValue: V): V {\n\tif (map.has(key)) {\n\t\treturn map.get(key)!\n\t}\n\tmap.set(key, defaultValue)\n\treturn defaultValue\n}\n"],
5
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/utils",
3
3
  "description": "tldraw infinite canvas SDK (private utilities).",
4
- "version": "5.4.0-next.09eca5dee30d",
4
+ "version": "5.4.0-next.0ccddf5733c3",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
package/src/lib/id.ts CHANGED
@@ -24,7 +24,7 @@ const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwy
24
24
  // request size by this multiplier. The pool is enlarged if subsequent
25
25
  // requests exceed the maximum buffer size.
26
26
  const POOL_SIZE_MULTIPLIER = 128
27
- let pool: Uint8Array, poolOffset: number
27
+ let pool: Uint8Array<ArrayBuffer>, poolOffset: number
28
28
 
29
29
  function fillPool(bytes: number) {
30
30
  if (!pool || pool.length < bytes) {
@@ -12,8 +12,8 @@ interface TldrawLibraryVersionInfo {
12
12
 
13
13
  const TLDRAW_LIBRARY_VERSION_KEY = '__TLDRAW_LIBRARY_VERSIONS__' as const
14
14
 
15
- // eslint-disable-next-line @typescript-eslint/prefer-namespace-keyword, @typescript-eslint/no-namespace, no-shadow-restricted-names
16
- declare module globalThis {
15
+ // eslint-disable-next-line @typescript-eslint/no-namespace, no-shadow-restricted-names
16
+ declare namespace globalThis {
17
17
  export const __TLDRAW_LIBRARY_VERSIONS__: TldrawLibraryVersionInfo
18
18
  }
19
19