@tldraw/editor 3.15.0-canary.bc8278557679 → 3.15.0-canary.c4b9179d0b38
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/dist-cjs/index.d.ts +41 -41
- package/dist-cjs/index.js +16 -16
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +20 -2
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +96 -101
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/primitives/intersect.js +4 -4
- package/dist-cjs/lib/primitives/intersect.js.map +2 -2
- package/dist-cjs/lib/primitives/utils.js +4 -0
- package/dist-cjs/lib/primitives/utils.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +0 -1
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +41 -41
- package/dist-esm/index.mjs +41 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +20 -2
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +96 -101
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/primitives/intersect.mjs +5 -5
- package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
- package/dist-esm/lib/primitives/utils.mjs +4 -0
- package/dist-esm/lib/primitives/utils.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +0 -1
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +62 -62
- package/src/lib/editor/Editor.test.ts +407 -0
- package/src/lib/editor/Editor.ts +29 -4
- package/src/lib/editor/managers/TextManager/TextManager.ts +108 -128
- package/src/lib/license/LicenseManager.test.ts +1 -1
- package/src/lib/primitives/intersect.test.ts +946 -0
- package/src/lib/primitives/intersect.ts +12 -5
- package/src/lib/primitives/utils.ts +11 -0
- package/src/lib/utils/sync/TLLocalSyncClient.ts +0 -1
- package/src/version.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/utils/sync/TLLocalSyncClient.ts"],
|
|
4
|
-
"sourcesContent": ["import { Signal, transact } from '@tldraw/state'\nimport { RecordsDiff, SerializedSchema, UnknownRecord, squashRecordDiffs } from '@tldraw/store'\nimport { TLStore } from '@tldraw/tlschema'\nimport { assert } from '@tldraw/utils'\nimport {\n\tTAB_ID,\n\tTLSessionStateSnapshot,\n\tcreateSessionStateSnapshotSignal,\n\textractSessionStateFromLegacySnapshot,\n\tloadSessionStateSnapshotIntoStore,\n} from '../../config/TLSessionStateSnapshot'\nimport { LocalIndexedDb } from './LocalIndexedDb'\nimport { showCantReadFromIndexDbAlert, showCantWriteToIndexDbAlert } from './alerts'\n\n/** How should we debounce persists? */\nconst PERSIST_THROTTLE_MS = 350\n/** If we're in an error state, how long should we wait before retrying a write? */\nconst PERSIST_RETRY_THROTTLE_MS = 10_000\n\nconst UPDATE_INSTANCE_STATE = Symbol('UPDATE_INSTANCE_STATE')\n\n/**\n * IMPORTANT!!!\n *\n * This is just a quick-n-dirty temporary solution that will be replaced with the remote sync client\n * once it has the db integrated\n */\n\ninterface SyncMessage {\n\ttype: 'diff'\n\tstoreId: string\n\tchanges: RecordsDiff<UnknownRecord>\n\tschema: SerializedSchema\n}\n\n// Sent by new clients when they connect\n// If another client is on the channel with a newer schema version\n// It will\ninterface AnnounceMessage {\n\ttype: 'announce'\n\tschema: SerializedSchema\n}\n\ntype Message = SyncMessage | AnnounceMessage\n\ntype UnpackPromise<T> = T extends Promise<infer U> ? U : T\n\nconst msg = (msg: Message) => msg\n\n/** @internal */\nexport class BroadcastChannelMock {\n\tonmessage?: (e: MessageEvent) => void\n\tconstructor(_name: string) {\n\t\t// noop\n\t}\n\tpostMessage(_msg: Message) {\n\t\t// noop\n\t}\n\tclose() {\n\t\t// noop\n\t}\n}\n\nconst BC = typeof BroadcastChannel === 'undefined' ? BroadcastChannelMock : BroadcastChannel\n\n/** @internal */\nexport class TLLocalSyncClient {\n\tprivate disposables = new Set<() => void>()\n\tprivate diffQueue: Array<RecordsDiff<UnknownRecord> | typeof UPDATE_INSTANCE_STATE> = []\n\tprivate didDispose = false\n\tprivate shouldDoFullDBWrite = true\n\tprivate isReloading = false\n\treadonly persistenceKey: string\n\treadonly sessionId: string\n\treadonly serializedSchema: SerializedSchema\n\tprivate isDebugging = false\n\tprivate readonly documentTypes: ReadonlySet<string>\n\tprivate readonly $sessionStateSnapshot: Signal<TLSessionStateSnapshot | null>\n\t/** @internal */\n\treadonly db: LocalIndexedDb\n\n\tinitTime = Date.now()\n\tprivate debug(...args: any[]) {\n\t\tif (this.isDebugging) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.debug(...args)\n\t\t}\n\t}\n\tconstructor(\n\t\tpublic readonly store: TLStore,\n\t\t{\n\t\t\tpersistenceKey,\n\t\t\tsessionId = TAB_ID,\n\t\t\tonLoad,\n\t\t\tonLoadError,\n\t\t}: {\n\t\t\tpersistenceKey: string\n\t\t\tsessionId?: string\n\t\t\tonLoad(self: TLLocalSyncClient): void\n\t\t\tonLoadError(error: Error): void\n\t\t},\n\t\tpublic readonly channel = new BC(`tldraw-tab-sync-${persistenceKey}`)\n\t) {\n\t\tif (typeof window !== 'undefined') {\n\t\t\t;(window as any).tlsync = this\n\t\t}\n\t\tthis.persistenceKey = persistenceKey\n\t\tthis.sessionId = sessionId\n\t\tthis.db = new LocalIndexedDb(persistenceKey)\n\t\tthis.disposables.add(() => this.db.close())\n\n\t\tthis.serializedSchema = this.store.schema.serialize()\n\t\tthis.$sessionStateSnapshot = createSessionStateSnapshotSignal(this.store)\n\n\t\tthis.disposables.add(\n\t\t\t// Set up a subscription to changes from the store: When\n\t\t\t// the store changes (and if the change was made by the user)\n\t\t\t// then immediately send the diff to other tabs via postMessage\n\t\t\t// and schedule a persist.\n\t\t\tstore.listen(\n\t\t\t\t({ changes }) => {\n\t\t\t\t\tthis.diffQueue.push(changes)\n\t\t\t\t\tthis.channel.postMessage(\n\t\t\t\t\t\tmsg({\n\t\t\t\t\t\t\ttype: 'diff',\n\t\t\t\t\t\t\tstoreId: this.store.id,\n\t\t\t\t\t\t\tchanges,\n\t\t\t\t\t\t\tschema: this.serializedSchema,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t\tthis.schedulePersist()\n\t\t\t\t},\n\t\t\t\t{ source: 'user', scope: 'document' }\n\t\t\t)\n\t\t)\n\t\tthis.disposables.add(\n\t\t\tstore.listen(\n\t\t\t\t() => {\n\t\t\t\t\tthis.diffQueue.push(UPDATE_INSTANCE_STATE)\n\t\t\t\t\tthis.schedulePersist()\n\t\t\t\t},\n\t\t\t\t{ scope: 'session' }\n\t\t\t)\n\t\t)\n\n\t\tthis.connect(onLoad, onLoadError)\n\n\t\tthis.documentTypes = new Set(\n\t\t\tObject.values(this.store.schema.types)\n\t\t\t\t.filter((t) => t.scope === 'document')\n\t\t\t\t.map((t) => t.typeName)\n\t\t)\n\t}\n\n\tprivate async connect(onLoad: (client: this) => void, onLoadError: (error: Error) => void) {\n\t\tthis.debug('connecting')\n\t\tlet data: UnpackPromise<ReturnType<LocalIndexedDb['load']>> | undefined\n\n\t\ttry {\n\t\t\tdata = await this.db.load({ sessionId: this.sessionId })\n\t\t} catch (error: any) {\n\t\t\tonLoadError(error)\n\t\t\tshowCantReadFromIndexDbAlert()\n\t\t\treturn\n\t\t}\n\n\t\tthis.debug('loaded data from store', data, 'didDispose', this.didDispose)\n\t\tif (this.didDispose) return\n\n\t\ttry {\n\t\t\tif (data) {\n\t\t\t\tconst documentSnapshot = Object.fromEntries(data.records.map((r) => [r.id, r]))\n\t\t\t\tconst sessionStateSnapshot =\n\t\t\t\t\tdata.sessionStateSnapshot ?? extractSessionStateFromLegacySnapshot(documentSnapshot)\n\t\t\t\tconst migrationResult = this.store.schema.migrateStoreSnapshot({\n\t\t\t\t\tstore: documentSnapshot,\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\tschema: data.schema ?? this.store.schema.serializeEarliestVersion(),\n\t\t\t\t})\n\n\t\t\t\tif (migrationResult.type === 'error') {\n\t\t\t\t\tconsole.error('failed to migrate store', migrationResult)\n\t\t\t\t\tonLoadError(new Error(`Failed to migrate store: ${migrationResult.reason}`))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst records = Object.values(migrationResult.value).filter((r) =>\n\t\t\t\t\tthis.documentTypes.has(r.typeName)\n\t\t\t\t)\n\t\t\t\tif (records.length > 0) {\n\t\t\t\t\t// 3. Merge the changes into the REAL STORE\n\t\t\t\t\tthis.store.mergeRemoteChanges(() => {\n\t\t\t\t\t\t// Calling put will validate the records!\n\t\t\t\t\t\tthis.store.put(records, 'initialize')\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tif (sessionStateSnapshot) {\n\t\t\t\t\tloadSessionStateSnapshotIntoStore(this.store, sessionStateSnapshot, {\n\t\t\t\t\t\tforceOverwrite: true,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.channel.onmessage = ({ data }) => {\n\t\t\t\tthis.debug('got message', data)\n\t\t\t\tconst msg = data as Message\n\t\t\t\t// if their schema is earlier than ours, we need to tell them so they can refresh\n\t\t\t\t// if their schema is later than ours, we need to refresh\n\t\t\t\tconst res = this.store.schema.getMigrationsSince(msg.schema)\n\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\t// we are older, refresh\n\t\t\t\t\t// but add a safety check to make sure we don't get in an infinite loop\n\t\t\t\t\tconst timeSinceInit = Date.now() - this.initTime\n\t\t\t\t\tif (timeSinceInit < 5000) {\n\t\t\t\t\t\t// This tab was just reloaded, but is out of date compared to other tabs.\n\t\t\t\t\t\t// Not expecting this to ever happen. It should only happen if we roll back a release that incremented\n\t\t\t\t\t\t// the schema version (which we should never do)\n\t\t\t\t\t\t// Or maybe during development if you have multiple local tabs open running the app on prod mode and you\n\t\t\t\t\t\t// check out an older commit. Dev server should be fine.\n\t\t\t\t\t\tonLoadError(new Error('Schema mismatch, please close other tabs and reload the page'))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tthis.debug('reloading')\n\t\t\t\t\tthis.isReloading = true\n\t\t\t\t\twindow?.location?.reload?.()\n\t\t\t\t\treturn\n\t\t\t\t} else if (res.value.length > 0) {\n\t\t\t\t\t// they are older, tell them to refresh and not write any more data\n\t\t\t\t\tthis.debug('telling them to reload')\n\t\t\t\t\tthis.channel.postMessage({ type: 'announce', schema: this.serializedSchema })\n\t\t\t\t\t// schedule a full db write in case they wrote data anyway\n\t\t\t\t\tthis.shouldDoFullDBWrite = true\n\t\t\t\t\tthis.persistIfNeeded()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// otherwise, all good, same version :)\n\t\t\t\tif (msg.type === 'diff') {\n\t\t\t\t\tthis.debug('applying diff')\n\t\t\t\t\ttransact(() => {\n\t\t\t\t\t\tthis.store.mergeRemoteChanges(() => {\n\t\t\t\t\t\t\tthis.store.applyDiff(msg.changes as any)\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\tthis.channel.postMessage({ type: 'announce', schema: this.serializedSchema })\n\t\t\tthis.disposables.add(() => {\n\t\t\t\tthis.channel.close()\n\t\t\t})\n\t\t\tonLoad(this)\n\t\t} catch (e: any) {\n\t\t\tthis.debug('error loading data from store', e)\n\t\t\tif (this.didDispose) return\n\t\t\tonLoadError(e)\n\t\t\treturn\n\t\t}\n\t}\n\n\tclose() {\n\t\tthis.debug('closing')\n\t\tthis.didDispose = true\n\t\tthis.disposables.forEach((d) => d())\n\t}\n\n\tprivate isPersisting = false\n\tprivate didLastWriteError = false\n\t// eslint-disable-next-line no-restricted-globals\n\tprivate scheduledPersistTimeout: ReturnType<typeof setTimeout> | null = null\n\n\t/**\n\t * Schedule a persist. Persists don't happen immediately: they are throttled to avoid writing too\n\t * often, and will retry if failed.\n\t *\n\t * @internal\n\t */\n\tprivate schedulePersist() {\n\t\tthis.debug('schedulePersist', this.scheduledPersistTimeout)\n\t\tif (this.scheduledPersistTimeout) return\n\t\t// eslint-disable-next-line no-restricted-globals\n\t\tthis.scheduledPersistTimeout = setTimeout(\n\t\t\t() => {\n\t\t\t\tthis.scheduledPersistTimeout = null\n\t\t\t\tthis.persistIfNeeded()\n\t\t\t},\n\t\t\tthis.didLastWriteError ? PERSIST_RETRY_THROTTLE_MS : PERSIST_THROTTLE_MS\n\t\t)\n\t}\n\n\t/**\n\t * Persist to IndexedDB only under certain circumstances:\n\t *\n\t * - If we're not already persisting\n\t * - If we're not reloading the page\n\t * - And we have something to persist (a full db write scheduled or changes in the diff queue)\n\t *\n\t * @internal\n\t */\n\tprivate persistIfNeeded() {\n\t\tthis.debug('persistIfNeeded', {\n\t\t\tisPersisting: this.isPersisting,\n\t\t\tisReloading: this.isReloading,\n\t\t\tshouldDoFullDBWrite: this.shouldDoFullDBWrite,\n\t\t\tdiffQueueLength: this.diffQueue.length,\n\t\t\tstoreIsPossiblyCorrupt: this.store.isPossiblyCorrupted(),\n\t\t})\n\n\t\t// if we've scheduled a persist for the future, that's no longer needed\n\t\tif (this.scheduledPersistTimeout) {\n\t\t\tclearTimeout(this.scheduledPersistTimeout)\n\t\t\tthis.scheduledPersistTimeout = null\n\t\t}\n\n\t\t// if a persist is already in progress, we don't need to do anything -\n\t\t// if there are still outstanding changes once it's finished, it'll\n\t\t// schedule another persist\n\t\tif (this.isPersisting) return\n\n\t\t// if we're reloading the page, it's because there's a newer client\n\t\t// present so lets not overwrite their changes\n\t\tif (this.isReloading) return\n\n\t\t// if the store is possibly corrupted, we don't want to persist\n\t\tif (this.store.isPossiblyCorrupted()) return\n\n\t\t// if we're scheduled for a full write or if we have changes outstanding, let's persist them!\n\t\tif (this.shouldDoFullDBWrite || this.diffQueue.length > 0) {\n\t\t\tthis.doPersist()\n\t\t}\n\t}\n\n\t/**\n\t * Actually persist to IndexedDB. If the write fails, then we'll retry with a full db write after\n\t * a short delay.\n\t */\n\tprivate async doPersist() {\n\t\tassert(!this.isPersisting, 'persist already in progress')\n\t\tif (this.didDispose) return\n\t\tthis.isPersisting = true\n\n\t\tthis.debug('doPersist start')\n\n\t\t// instantly empty the diff queue, but keep our own copy of it. this way\n\t\t// diffs that come in during the persist will still get tracked\n\t\tconst diffQueue = this.diffQueue\n\t\tthis.diffQueue = []\n\n\t\ttry {\n\t\t\tif (this.shouldDoFullDBWrite) {\n\t\t\t\tthis.shouldDoFullDBWrite = false\n\t\t\t\tawait this.db.storeSnapshot({\n\t\t\t\t\tschema: this.store.schema,\n\t\t\t\t\tsnapshot: this.store.serialize(),\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionStateSnapshot: this.$sessionStateSnapshot.get(),\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tconst diffs = squashRecordDiffs(\n\t\t\t\t\tdiffQueue.filter((d): d is RecordsDiff<UnknownRecord> => d !== UPDATE_INSTANCE_STATE)\n\t\t\t\t)\n\t\t\t\tawait this.db.storeChanges({\n\t\t\t\t\tchanges: diffs,\n\t\t\t\t\tschema: this.store.schema,\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionStateSnapshot: this.$sessionStateSnapshot.get(),\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.didLastWriteError = false\n\t\t} catch (e) {\n\t\t\t// set this.shouldDoFullDBWrite because we clear the diffQueue no matter what,\n\t\t\t// so if this is just a temporary error, we will still persist all changes\n\t\t\tthis.shouldDoFullDBWrite = true\n\t\t\tthis.didLastWriteError = true\n\t\t\tconsole.error('failed to store changes in indexed db', e)\n\n\t\t\tshowCantWriteToIndexDbAlert()\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\t// adios\n\t\t\t\twindow.location.reload()\n\t\t\t}\n\t\t}\n\n\t\tthis.isPersisting = false\n\t\tthis.debug('doPersist end')\n\n\t\t// changes might have come in between when we started the persist and\n\t\t// now. we request another persist so any new changes can get written\n\t\tthis.schedulePersist()\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { Signal, transact } from '@tldraw/state'\nimport { RecordsDiff, SerializedSchema, UnknownRecord, squashRecordDiffs } from '@tldraw/store'\nimport { TLStore } from '@tldraw/tlschema'\nimport { assert } from '@tldraw/utils'\nimport {\n\tTAB_ID,\n\tTLSessionStateSnapshot,\n\tcreateSessionStateSnapshotSignal,\n\textractSessionStateFromLegacySnapshot,\n\tloadSessionStateSnapshotIntoStore,\n} from '../../config/TLSessionStateSnapshot'\nimport { LocalIndexedDb } from './LocalIndexedDb'\nimport { showCantReadFromIndexDbAlert, showCantWriteToIndexDbAlert } from './alerts'\n\n/** How should we debounce persists? */\nconst PERSIST_THROTTLE_MS = 350\n/** If we're in an error state, how long should we wait before retrying a write? */\nconst PERSIST_RETRY_THROTTLE_MS = 10_000\n\nconst UPDATE_INSTANCE_STATE = Symbol('UPDATE_INSTANCE_STATE')\n\n/**\n * IMPORTANT!!!\n *\n * This is just a quick-n-dirty temporary solution that will be replaced with the remote sync client\n * once it has the db integrated\n */\n\ninterface SyncMessage {\n\ttype: 'diff'\n\tstoreId: string\n\tchanges: RecordsDiff<UnknownRecord>\n\tschema: SerializedSchema\n}\n\n// Sent by new clients when they connect\n// If another client is on the channel with a newer schema version\n// It will\ninterface AnnounceMessage {\n\ttype: 'announce'\n\tschema: SerializedSchema\n}\n\ntype Message = SyncMessage | AnnounceMessage\n\ntype UnpackPromise<T> = T extends Promise<infer U> ? U : T\n\nconst msg = (msg: Message) => msg\n\n/** @internal */\nexport class BroadcastChannelMock {\n\tonmessage?: (e: MessageEvent) => void\n\tconstructor(_name: string) {\n\t\t// noop\n\t}\n\tpostMessage(_msg: Message) {\n\t\t// noop\n\t}\n\tclose() {\n\t\t// noop\n\t}\n}\n\nconst BC = typeof BroadcastChannel === 'undefined' ? BroadcastChannelMock : BroadcastChannel\n\n/** @internal */\nexport class TLLocalSyncClient {\n\tprivate disposables = new Set<() => void>()\n\tprivate diffQueue: Array<RecordsDiff<UnknownRecord> | typeof UPDATE_INSTANCE_STATE> = []\n\tprivate didDispose = false\n\tprivate shouldDoFullDBWrite = true\n\tprivate isReloading = false\n\treadonly persistenceKey: string\n\treadonly sessionId: string\n\treadonly serializedSchema: SerializedSchema\n\tprivate isDebugging = false\n\tprivate readonly documentTypes: ReadonlySet<string>\n\tprivate readonly $sessionStateSnapshot: Signal<TLSessionStateSnapshot | null>\n\t/** @internal */\n\treadonly db: LocalIndexedDb\n\n\tinitTime = Date.now()\n\tprivate debug(...args: any[]) {\n\t\tif (this.isDebugging) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.debug(...args)\n\t\t}\n\t}\n\tconstructor(\n\t\tpublic readonly store: TLStore,\n\t\t{\n\t\t\tpersistenceKey,\n\t\t\tsessionId = TAB_ID,\n\t\t\tonLoad,\n\t\t\tonLoadError,\n\t\t}: {\n\t\t\tpersistenceKey: string\n\t\t\tsessionId?: string\n\t\t\tonLoad(self: TLLocalSyncClient): void\n\t\t\tonLoadError(error: Error): void\n\t\t},\n\t\tpublic readonly channel = new BC(`tldraw-tab-sync-${persistenceKey}`)\n\t) {\n\t\tif (typeof window !== 'undefined') {\n\t\t\t;(window as any).tlsync = this\n\t\t}\n\t\tthis.persistenceKey = persistenceKey\n\t\tthis.sessionId = sessionId\n\t\tthis.db = new LocalIndexedDb(persistenceKey)\n\t\tthis.disposables.add(() => this.db.close())\n\n\t\tthis.serializedSchema = this.store.schema.serialize()\n\t\tthis.$sessionStateSnapshot = createSessionStateSnapshotSignal(this.store)\n\n\t\tthis.disposables.add(\n\t\t\t// Set up a subscription to changes from the store: When\n\t\t\t// the store changes (and if the change was made by the user)\n\t\t\t// then immediately send the diff to other tabs via postMessage\n\t\t\t// and schedule a persist.\n\t\t\tstore.listen(\n\t\t\t\t({ changes }) => {\n\t\t\t\t\tthis.diffQueue.push(changes)\n\t\t\t\t\tthis.channel.postMessage(\n\t\t\t\t\t\tmsg({\n\t\t\t\t\t\t\ttype: 'diff',\n\t\t\t\t\t\t\tstoreId: this.store.id,\n\t\t\t\t\t\t\tchanges,\n\t\t\t\t\t\t\tschema: this.serializedSchema,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t\tthis.schedulePersist()\n\t\t\t\t},\n\t\t\t\t{ source: 'user', scope: 'document' }\n\t\t\t)\n\t\t)\n\t\tthis.disposables.add(\n\t\t\tstore.listen(\n\t\t\t\t() => {\n\t\t\t\t\tthis.diffQueue.push(UPDATE_INSTANCE_STATE)\n\t\t\t\t\tthis.schedulePersist()\n\t\t\t\t},\n\t\t\t\t{ scope: 'session' }\n\t\t\t)\n\t\t)\n\n\t\tthis.connect(onLoad, onLoadError)\n\n\t\tthis.documentTypes = new Set(\n\t\t\tObject.values(this.store.schema.types)\n\t\t\t\t.filter((t) => t.scope === 'document')\n\t\t\t\t.map((t) => t.typeName)\n\t\t)\n\t}\n\n\tprivate async connect(onLoad: (client: this) => void, onLoadError: (error: Error) => void) {\n\t\tthis.debug('connecting')\n\t\tlet data: UnpackPromise<ReturnType<LocalIndexedDb['load']>> | undefined\n\n\t\ttry {\n\t\t\tdata = await this.db.load({ sessionId: this.sessionId })\n\t\t} catch (error: any) {\n\t\t\tonLoadError(error)\n\t\t\tshowCantReadFromIndexDbAlert()\n\t\t\treturn\n\t\t}\n\n\t\tthis.debug('loaded data from store', data, 'didDispose', this.didDispose)\n\t\tif (this.didDispose) return\n\n\t\ttry {\n\t\t\tif (data) {\n\t\t\t\tconst documentSnapshot = Object.fromEntries(data.records.map((r) => [r.id, r]))\n\t\t\t\tconst sessionStateSnapshot =\n\t\t\t\t\tdata.sessionStateSnapshot ?? extractSessionStateFromLegacySnapshot(documentSnapshot)\n\t\t\t\tconst migrationResult = this.store.schema.migrateStoreSnapshot({\n\t\t\t\t\tstore: documentSnapshot,\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\tschema: data.schema ?? this.store.schema.serializeEarliestVersion(),\n\t\t\t\t})\n\n\t\t\t\tif (migrationResult.type === 'error') {\n\t\t\t\t\tconsole.error('failed to migrate store', migrationResult)\n\t\t\t\t\tonLoadError(new Error(`Failed to migrate store: ${migrationResult.reason}`))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst records = Object.values(migrationResult.value).filter((r) =>\n\t\t\t\t\tthis.documentTypes.has(r.typeName)\n\t\t\t\t)\n\t\t\t\tif (records.length > 0) {\n\t\t\t\t\t// 3. Merge the changes into the REAL STORE\n\t\t\t\t\tthis.store.mergeRemoteChanges(() => {\n\t\t\t\t\t\t// Calling put will validate the records!\n\t\t\t\t\t\tthis.store.put(records, 'initialize')\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tif (sessionStateSnapshot) {\n\t\t\t\t\tloadSessionStateSnapshotIntoStore(this.store, sessionStateSnapshot, {\n\t\t\t\t\t\tforceOverwrite: true,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.channel.onmessage = ({ data }) => {\n\t\t\t\tthis.debug('got message', data)\n\t\t\t\tconst msg = data as Message\n\t\t\t\t// if their schema is earlier than ours, we need to tell them so they can refresh\n\t\t\t\t// if their schema is later than ours, we need to refresh\n\t\t\t\tconst res = this.store.schema.getMigrationsSince(msg.schema)\n\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\t// we are older, refresh\n\t\t\t\t\t// but add a safety check to make sure we don't get in an infinite loop\n\t\t\t\t\tconst timeSinceInit = Date.now() - this.initTime\n\t\t\t\t\tif (timeSinceInit < 5000) {\n\t\t\t\t\t\t// This tab was just reloaded, but is out of date compared to other tabs.\n\t\t\t\t\t\t// Not expecting this to ever happen. It should only happen if we roll back a release that incremented\n\t\t\t\t\t\t// the schema version (which we should never do)\n\t\t\t\t\t\t// Or maybe during development if you have multiple local tabs open running the app on prod mode and you\n\t\t\t\t\t\t// check out an older commit. Dev server should be fine.\n\t\t\t\t\t\tonLoadError(new Error('Schema mismatch, please close other tabs and reload the page'))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tthis.debug('reloading')\n\t\t\t\t\tthis.isReloading = true\n\t\t\t\t\twindow?.location?.reload?.()\n\t\t\t\t\treturn\n\t\t\t\t} else if (res.value.length > 0) {\n\t\t\t\t\t// they are older, tell them to refresh and not write any more data\n\t\t\t\t\tthis.debug('telling them to reload')\n\t\t\t\t\tthis.channel.postMessage({ type: 'announce', schema: this.serializedSchema })\n\t\t\t\t\t// schedule a full db write in case they wrote data anyway\n\t\t\t\t\tthis.shouldDoFullDBWrite = true\n\t\t\t\t\tthis.persistIfNeeded()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// otherwise, all good, same version :)\n\t\t\t\tif (msg.type === 'diff') {\n\t\t\t\t\tthis.debug('applying diff')\n\t\t\t\t\ttransact(() => {\n\t\t\t\t\t\tthis.store.mergeRemoteChanges(() => {\n\t\t\t\t\t\t\tthis.store.applyDiff(msg.changes as any)\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\tthis.channel.postMessage({ type: 'announce', schema: this.serializedSchema })\n\t\t\tthis.disposables.add(() => {\n\t\t\t\tthis.channel.close()\n\t\t\t})\n\t\t\tonLoad(this)\n\t\t} catch (e: any) {\n\t\t\tthis.debug('error loading data from store', e)\n\t\t\tif (this.didDispose) return\n\t\t\tonLoadError(e)\n\t\t\treturn\n\t\t}\n\t}\n\n\tclose() {\n\t\tthis.debug('closing')\n\t\tthis.didDispose = true\n\t\tthis.disposables.forEach((d) => d())\n\t}\n\n\tprivate isPersisting = false\n\tprivate didLastWriteError = false\n\tprivate scheduledPersistTimeout: ReturnType<typeof setTimeout> | null = null\n\n\t/**\n\t * Schedule a persist. Persists don't happen immediately: they are throttled to avoid writing too\n\t * often, and will retry if failed.\n\t *\n\t * @internal\n\t */\n\tprivate schedulePersist() {\n\t\tthis.debug('schedulePersist', this.scheduledPersistTimeout)\n\t\tif (this.scheduledPersistTimeout) return\n\t\t// eslint-disable-next-line no-restricted-globals\n\t\tthis.scheduledPersistTimeout = setTimeout(\n\t\t\t() => {\n\t\t\t\tthis.scheduledPersistTimeout = null\n\t\t\t\tthis.persistIfNeeded()\n\t\t\t},\n\t\t\tthis.didLastWriteError ? PERSIST_RETRY_THROTTLE_MS : PERSIST_THROTTLE_MS\n\t\t)\n\t}\n\n\t/**\n\t * Persist to IndexedDB only under certain circumstances:\n\t *\n\t * - If we're not already persisting\n\t * - If we're not reloading the page\n\t * - And we have something to persist (a full db write scheduled or changes in the diff queue)\n\t *\n\t * @internal\n\t */\n\tprivate persistIfNeeded() {\n\t\tthis.debug('persistIfNeeded', {\n\t\t\tisPersisting: this.isPersisting,\n\t\t\tisReloading: this.isReloading,\n\t\t\tshouldDoFullDBWrite: this.shouldDoFullDBWrite,\n\t\t\tdiffQueueLength: this.diffQueue.length,\n\t\t\tstoreIsPossiblyCorrupt: this.store.isPossiblyCorrupted(),\n\t\t})\n\n\t\t// if we've scheduled a persist for the future, that's no longer needed\n\t\tif (this.scheduledPersistTimeout) {\n\t\t\tclearTimeout(this.scheduledPersistTimeout)\n\t\t\tthis.scheduledPersistTimeout = null\n\t\t}\n\n\t\t// if a persist is already in progress, we don't need to do anything -\n\t\t// if there are still outstanding changes once it's finished, it'll\n\t\t// schedule another persist\n\t\tif (this.isPersisting) return\n\n\t\t// if we're reloading the page, it's because there's a newer client\n\t\t// present so lets not overwrite their changes\n\t\tif (this.isReloading) return\n\n\t\t// if the store is possibly corrupted, we don't want to persist\n\t\tif (this.store.isPossiblyCorrupted()) return\n\n\t\t// if we're scheduled for a full write or if we have changes outstanding, let's persist them!\n\t\tif (this.shouldDoFullDBWrite || this.diffQueue.length > 0) {\n\t\t\tthis.doPersist()\n\t\t}\n\t}\n\n\t/**\n\t * Actually persist to IndexedDB. If the write fails, then we'll retry with a full db write after\n\t * a short delay.\n\t */\n\tprivate async doPersist() {\n\t\tassert(!this.isPersisting, 'persist already in progress')\n\t\tif (this.didDispose) return\n\t\tthis.isPersisting = true\n\n\t\tthis.debug('doPersist start')\n\n\t\t// instantly empty the diff queue, but keep our own copy of it. this way\n\t\t// diffs that come in during the persist will still get tracked\n\t\tconst diffQueue = this.diffQueue\n\t\tthis.diffQueue = []\n\n\t\ttry {\n\t\t\tif (this.shouldDoFullDBWrite) {\n\t\t\t\tthis.shouldDoFullDBWrite = false\n\t\t\t\tawait this.db.storeSnapshot({\n\t\t\t\t\tschema: this.store.schema,\n\t\t\t\t\tsnapshot: this.store.serialize(),\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionStateSnapshot: this.$sessionStateSnapshot.get(),\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tconst diffs = squashRecordDiffs(\n\t\t\t\t\tdiffQueue.filter((d): d is RecordsDiff<UnknownRecord> => d !== UPDATE_INSTANCE_STATE)\n\t\t\t\t)\n\t\t\t\tawait this.db.storeChanges({\n\t\t\t\t\tchanges: diffs,\n\t\t\t\t\tschema: this.store.schema,\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionStateSnapshot: this.$sessionStateSnapshot.get(),\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.didLastWriteError = false\n\t\t} catch (e) {\n\t\t\t// set this.shouldDoFullDBWrite because we clear the diffQueue no matter what,\n\t\t\t// so if this is just a temporary error, we will still persist all changes\n\t\t\tthis.shouldDoFullDBWrite = true\n\t\t\tthis.didLastWriteError = true\n\t\t\tconsole.error('failed to store changes in indexed db', e)\n\n\t\t\tshowCantWriteToIndexDbAlert()\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\t// adios\n\t\t\t\twindow.location.reload()\n\t\t\t}\n\t\t}\n\n\t\tthis.isPersisting = false\n\t\tthis.debug('doPersist end')\n\n\t\t// changes might have come in between when we started the persist and\n\t\t// now. we request another persist so any new changes can get written\n\t\tthis.schedulePersist()\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["msg", "data"]
|
|
7
7
|
}
|
package/dist-cjs/version.js
CHANGED
|
@@ -22,10 +22,10 @@ __export(version_exports, {
|
|
|
22
22
|
version: () => version
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(version_exports);
|
|
25
|
-
const version = "3.15.0-canary.
|
|
25
|
+
const version = "3.15.0-canary.c4b9179d0b38";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2024-09-13T14:36:29.063Z",
|
|
28
|
-
minor: "2025-07-
|
|
29
|
-
patch: "2025-07-
|
|
28
|
+
minor: "2025-07-10T09:51:38.777Z",
|
|
29
|
+
patch: "2025-07-10T09:51:38.777Z"
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=version.js.map
|
package/dist-cjs/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.15.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.15.0-canary.c4b9179d0b38'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-07-10T09:51:38.777Z',\n\tpatch: '2025-07-10T09:51:38.777Z',\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/index.d.mts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
|
|
3
1
|
import { Atom } from '@tldraw/state';
|
|
4
2
|
import { BoxModel } from '@tldraw/tlschema';
|
|
5
3
|
import { ComponentType } from 'react';
|
|
@@ -19,8 +17,8 @@ import { NamedExoticComponent } from 'react';
|
|
|
19
17
|
import { Node as Node_2 } from '@tiptap/pm/model';
|
|
20
18
|
import { PerformanceTracker } from '@tldraw/utils';
|
|
21
19
|
import { PointerEventHandler } from 'react';
|
|
22
|
-
import
|
|
23
|
-
import
|
|
20
|
+
import * as React_2 from 'react';
|
|
21
|
+
import { default as React_3 } from 'react';
|
|
24
22
|
import { ReactElement } from 'react';
|
|
25
23
|
import { ReactNode } from 'react';
|
|
26
24
|
import { RecordProps } from '@tldraw/tlschema';
|
|
@@ -59,6 +57,7 @@ import { TLImageAsset } from '@tldraw/tlschema';
|
|
|
59
57
|
import { TLInstance } from '@tldraw/tlschema';
|
|
60
58
|
import { TLInstancePageState } from '@tldraw/tlschema';
|
|
61
59
|
import { TLInstancePresence } from '@tldraw/tlschema';
|
|
60
|
+
import { TLOpacityType } from '@tldraw/tlschema';
|
|
62
61
|
import { TLPage } from '@tldraw/tlschema';
|
|
63
62
|
import { TLPageId } from '@tldraw/tlschema';
|
|
64
63
|
import { TLParentId } from '@tldraw/tlschema';
|
|
@@ -716,8 +715,8 @@ export declare function createTLStore({ initialData, defaultName, id, assets, on
|
|
|
716
715
|
|
|
717
716
|
/** @public */
|
|
718
717
|
export declare function createTLUser(opts?: {
|
|
719
|
-
setUserPreferences?: (
|
|
720
|
-
userPreferences?: Signal<TLUserPreferences
|
|
718
|
+
setUserPreferences?: (userPreferences: TLUserPreferences) => void;
|
|
719
|
+
userPreferences?: Signal<TLUserPreferences>;
|
|
721
720
|
}): TLUser;
|
|
722
721
|
|
|
723
722
|
/** @public */
|
|
@@ -848,7 +847,7 @@ export declare const defaultTldrawOptions: {
|
|
|
848
847
|
readonly edgeScrollSpeed: 25;
|
|
849
848
|
readonly enableToolbarKeyboardShortcuts: true;
|
|
850
849
|
readonly exportProvider: ExoticComponent< {
|
|
851
|
-
children?: ReactNode;
|
|
850
|
+
children?: ReactNode | undefined;
|
|
852
851
|
}>;
|
|
853
852
|
readonly flattenImageBoundsExpand: 64;
|
|
854
853
|
readonly flattenImageBoundsPadding: 16;
|
|
@@ -1019,8 +1018,8 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
1019
1018
|
readonly timers: {
|
|
1020
1019
|
dispose: () => void;
|
|
1021
1020
|
requestAnimationFrame: (callback: FrameRequestCallback) => number;
|
|
1022
|
-
setInterval: (handler: TimerHandler, timeout?: number
|
|
1023
|
-
setTimeout: (handler: TimerHandler, timeout?: number
|
|
1021
|
+
setInterval: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
|
|
1022
|
+
setTimeout: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
|
|
1024
1023
|
};
|
|
1025
1024
|
/**
|
|
1026
1025
|
* A manager for the user and their preferences.
|
|
@@ -1554,7 +1553,9 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
1554
1553
|
*/
|
|
1555
1554
|
deselect(...shapes: TLShape[] | TLShapeId[]): this;
|
|
1556
1555
|
/**
|
|
1557
|
-
* Select all
|
|
1556
|
+
* Select all shapes. If the user has selected shapes that share a parent,
|
|
1557
|
+
* select all shapes within that parent. If the user has not selected any shapes,
|
|
1558
|
+
* or if the shapes shapes are only on select all shapes on the current page.
|
|
1558
1559
|
*
|
|
1559
1560
|
* @example
|
|
1560
1561
|
* ```ts
|
|
@@ -2069,10 +2070,10 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2069
2070
|
*/
|
|
2070
2071
|
slideCamera(opts?: {
|
|
2071
2072
|
direction: VecLike;
|
|
2072
|
-
force?: boolean
|
|
2073
|
-
friction?: number
|
|
2073
|
+
force?: boolean;
|
|
2074
|
+
friction?: number;
|
|
2074
2075
|
speed: number;
|
|
2075
|
-
speedThreshold?: number
|
|
2076
|
+
speedThreshold?: number;
|
|
2076
2077
|
}): this;
|
|
2077
2078
|
/**
|
|
2078
2079
|
* Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.
|
|
@@ -2684,12 +2685,12 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2684
2685
|
*/
|
|
2685
2686
|
getShapeAtPoint(point: VecLike, opts?: {
|
|
2686
2687
|
filter?(shape: TLShape): boolean;
|
|
2687
|
-
hitFrameInside?: boolean
|
|
2688
|
-
hitInside?: boolean
|
|
2689
|
-
hitLabels?: boolean
|
|
2690
|
-
hitLocked?: boolean
|
|
2691
|
-
margin?: number
|
|
2692
|
-
renderingOnly?: boolean
|
|
2688
|
+
hitFrameInside?: boolean;
|
|
2689
|
+
hitInside?: boolean;
|
|
2690
|
+
hitLabels?: boolean;
|
|
2691
|
+
hitLocked?: boolean;
|
|
2692
|
+
margin?: number;
|
|
2693
|
+
renderingOnly?: boolean;
|
|
2693
2694
|
}): TLShape | undefined;
|
|
2694
2695
|
/**
|
|
2695
2696
|
* Get the shapes, if any, at a given page point.
|
|
@@ -2708,8 +2709,8 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2708
2709
|
* @public
|
|
2709
2710
|
*/
|
|
2710
2711
|
getShapesAtPoint(point: VecLike, opts?: {
|
|
2711
|
-
hitInside?: boolean
|
|
2712
|
-
margin?: number
|
|
2712
|
+
hitInside?: boolean;
|
|
2713
|
+
margin?: number;
|
|
2713
2714
|
}): TLShape[];
|
|
2714
2715
|
/**
|
|
2715
2716
|
* Test whether a point (in the current page space) will will a shape. This method takes into account masks,
|
|
@@ -2727,8 +2728,8 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2727
2728
|
* @public
|
|
2728
2729
|
*/
|
|
2729
2730
|
isPointInShape(shape: TLShape | TLShapeId, point: VecLike, opts?: {
|
|
2730
|
-
hitInside?: boolean
|
|
2731
|
-
margin?: number
|
|
2731
|
+
hitInside?: boolean;
|
|
2732
|
+
margin?: number;
|
|
2732
2733
|
}): boolean;
|
|
2733
2734
|
/**
|
|
2734
2735
|
* Convert a point in the current page space to a point in the local space of a shape. For example, if a
|
|
@@ -4014,7 +4015,7 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
4014
4015
|
}
|
|
4015
4016
|
|
|
4016
4017
|
/** @public */
|
|
4017
|
-
export declare const EditorContext:
|
|
4018
|
+
export declare const EditorContext: React_3.Context<Editor | null>;
|
|
4018
4019
|
|
|
4019
4020
|
/** @public @react */
|
|
4020
4021
|
export declare function EditorProvider({ editor, children }: EditorProviderProps): JSX_2.Element;
|
|
@@ -4022,7 +4023,7 @@ export declare function EditorProvider({ editor, children }: EditorProviderProps
|
|
|
4022
4023
|
/** @public */
|
|
4023
4024
|
export declare interface EditorProviderProps {
|
|
4024
4025
|
editor: Editor;
|
|
4025
|
-
children:
|
|
4026
|
+
children: React_3.ReactNode;
|
|
4026
4027
|
}
|
|
4027
4028
|
|
|
4028
4029
|
/** @public */
|
|
@@ -4048,7 +4049,7 @@ export declare class Ellipse2d extends Geometry2d {
|
|
|
4048
4049
|
}
|
|
4049
4050
|
|
|
4050
4051
|
/** @public */
|
|
4051
|
-
export declare class ErrorBoundary extends
|
|
4052
|
+
export declare class ErrorBoundary extends React_2.Component<React_2.PropsWithRef<React_2.PropsWithChildren<TLErrorBoundaryProps>>, {
|
|
4052
4053
|
error: Error | null;
|
|
4053
4054
|
}> {
|
|
4054
4055
|
static getDerivedStateFromError(error: Error): {
|
|
@@ -4058,7 +4059,7 @@ export declare class ErrorBoundary extends React_3.Component<React_3.PropsWithRe
|
|
|
4058
4059
|
error: null;
|
|
4059
4060
|
};
|
|
4060
4061
|
componentDidCatch(error: unknown): void;
|
|
4061
|
-
render(): boolean | JSX_2.Element | Iterable<
|
|
4062
|
+
render(): boolean | JSX_2.Element | Iterable<React_2.ReactNode> | null | number | string | undefined;
|
|
4062
4063
|
}
|
|
4063
4064
|
|
|
4064
4065
|
/** @public @react */
|
|
@@ -4462,7 +4463,7 @@ export declare class HistoryManager<R extends UnknownRecord> {
|
|
|
4462
4463
|
export declare function HTMLContainer({ children, className, ...rest }: HTMLContainerProps): JSX_2.Element;
|
|
4463
4464
|
|
|
4464
4465
|
/** @public */
|
|
4465
|
-
export declare type HTMLContainerProps =
|
|
4466
|
+
export declare type HTMLContainerProps = React_2.HTMLAttributes<HTMLDivElement>;
|
|
4466
4467
|
|
|
4467
4468
|
/** @public */
|
|
4468
4469
|
export declare const inlineBase64AssetStore: TLAssetStore;
|
|
@@ -4518,7 +4519,7 @@ export declare function intersectLineSegmentCircle(a1: VecLike, a2: VecLike, c:
|
|
|
4518
4519
|
* @param b2 - The second segment's second point.
|
|
4519
4520
|
* @public
|
|
4520
4521
|
*/
|
|
4521
|
-
export declare function intersectLineSegmentLineSegment(a1: VecLike, a2: VecLike, b1: VecLike, b2: VecLike): null | Vec;
|
|
4522
|
+
export declare function intersectLineSegmentLineSegment(a1: VecLike, a2: VecLike, b1: VecLike, b2: VecLike, precision?: number): null | Vec;
|
|
4522
4523
|
|
|
4523
4524
|
/**
|
|
4524
4525
|
* Find the intersections between a line segment and a closed polygon.
|
|
@@ -4824,7 +4825,7 @@ export declare function precise(A: VecLike): string;
|
|
|
4824
4825
|
* @param event - To prevent default on
|
|
4825
4826
|
* @public
|
|
4826
4827
|
*/
|
|
4827
|
-
export declare function preventDefault(event: Event |
|
|
4828
|
+
export declare function preventDefault(event: Event | React_3.BaseSyntheticEvent): void;
|
|
4828
4829
|
|
|
4829
4830
|
/**
|
|
4830
4831
|
* Convert radians to degrees.
|
|
@@ -4859,10 +4860,10 @@ export declare class ReadonlySharedStyleMap {
|
|
|
4859
4860
|
getAsKnownValue<T>(prop: StyleProp<T>): T | undefined;
|
|
4860
4861
|
get size(): number;
|
|
4861
4862
|
equals(other: ReadonlySharedStyleMap): boolean;
|
|
4862
|
-
keys():
|
|
4863
|
-
values():
|
|
4864
|
-
entries():
|
|
4865
|
-
[Symbol.iterator]():
|
|
4863
|
+
keys(): MapIterator<StyleProp<any>>;
|
|
4864
|
+
values(): MapIterator<SharedStyle<unknown>>;
|
|
4865
|
+
entries(): MapIterator<[StyleProp<any>, SharedStyle<unknown>]>;
|
|
4866
|
+
[Symbol.iterator](): MapIterator<[StyleProp<any>, SharedStyle<unknown>]>;
|
|
4866
4867
|
}
|
|
4867
4868
|
|
|
4868
4869
|
/** @public */
|
|
@@ -4886,7 +4887,7 @@ export declare class Rectangle2d extends Polygon2d {
|
|
|
4886
4887
|
export declare function refreshPage(): void;
|
|
4887
4888
|
|
|
4888
4889
|
/** @public */
|
|
4889
|
-
export declare function releasePointerCapture(element: Element, event: PointerEvent |
|
|
4890
|
+
export declare function releasePointerCapture(element: Element, event: PointerEvent | React_3.PointerEvent<Element>): void;
|
|
4890
4891
|
|
|
4891
4892
|
/** @public */
|
|
4892
4893
|
export declare type RequiredKeys<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;
|
|
@@ -5029,7 +5030,7 @@ export declare type SelectionEdge = 'bottom' | 'left' | 'right' | 'top';
|
|
|
5029
5030
|
export declare type SelectionHandle = SelectionCorner | SelectionEdge;
|
|
5030
5031
|
|
|
5031
5032
|
/** @public */
|
|
5032
|
-
export declare function setPointerCapture(element: Element, event: PointerEvent |
|
|
5033
|
+
export declare function setPointerCapture(element: Element, event: PointerEvent | React_3.PointerEvent<Element>): void;
|
|
5033
5034
|
|
|
5034
5035
|
/** @public */
|
|
5035
5036
|
export declare function setRuntimeOverrides(input: Partial<typeof runtime>): void;
|
|
@@ -5735,7 +5736,7 @@ export declare function suffixSafeId(id: SafeId, suffix: string): SafeId;
|
|
|
5735
5736
|
export declare function SVGContainer({ children, className, ...rest }: SVGContainerProps): JSX_2.Element;
|
|
5736
5737
|
|
|
5737
5738
|
/** @public */
|
|
5738
|
-
export declare type SVGContainerProps =
|
|
5739
|
+
export declare type SVGContainerProps = React_2.ComponentProps<'svg'>;
|
|
5739
5740
|
|
|
5740
5741
|
/** @public */
|
|
5741
5742
|
export declare interface SvgExportContext {
|
|
@@ -5796,10 +5797,9 @@ export declare const TAB_ID: string;
|
|
|
5796
5797
|
export declare class TextManager {
|
|
5797
5798
|
editor: Editor;
|
|
5798
5799
|
private elm;
|
|
5799
|
-
private defaultStyles;
|
|
5800
5800
|
constructor(editor: Editor);
|
|
5801
|
+
private setElementStyles;
|
|
5801
5802
|
dispose(): void;
|
|
5802
|
-
private resetElmStyles;
|
|
5803
5803
|
measureText(textToMeasure: string, opts: TLMeasureTextOpts): BoxModel & {
|
|
5804
5804
|
scrollWidth: number;
|
|
5805
5805
|
};
|
|
@@ -6143,7 +6143,7 @@ export declare interface TLDragShapesOverInfo {
|
|
|
6143
6143
|
}
|
|
6144
6144
|
|
|
6145
6145
|
/** @public @react */
|
|
6146
|
-
export declare const TldrawEditor:
|
|
6146
|
+
export declare const TldrawEditor: React_3.NamedExoticComponent<TldrawEditorProps>;
|
|
6147
6147
|
|
|
6148
6148
|
/**
|
|
6149
6149
|
* Base props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components.
|
|
@@ -6547,7 +6547,7 @@ export declare const tlenv: {
|
|
|
6547
6547
|
|
|
6548
6548
|
/** @public */
|
|
6549
6549
|
export declare interface TLErrorBoundaryProps {
|
|
6550
|
-
children:
|
|
6550
|
+
children: React_2.ReactNode;
|
|
6551
6551
|
onError?: ((error: unknown) => void) | null;
|
|
6552
6552
|
fallback: TLErrorFallbackComponent;
|
|
6553
6553
|
}
|
package/dist-esm/index.mjs
CHANGED
|
@@ -10,19 +10,6 @@ export * from "@tldraw/store";
|
|
|
10
10
|
export * from "@tldraw/tlschema";
|
|
11
11
|
export * from "@tldraw/utils";
|
|
12
12
|
export * from "@tldraw/validate";
|
|
13
|
-
import {
|
|
14
|
-
ErrorScreen,
|
|
15
|
-
LoadingScreen,
|
|
16
|
-
TldrawEditor,
|
|
17
|
-
useOnMount
|
|
18
|
-
} from "./lib/TldrawEditor.mjs";
|
|
19
|
-
import {
|
|
20
|
-
ErrorBoundary,
|
|
21
|
-
OptionalErrorBoundary
|
|
22
|
-
} from "./lib/components/ErrorBoundary.mjs";
|
|
23
|
-
import { HTMLContainer } from "./lib/components/HTMLContainer.mjs";
|
|
24
|
-
import { MenuClickCapture } from "./lib/components/MenuClickCapture.mjs";
|
|
25
|
-
import { SVGContainer } from "./lib/components/SVGContainer.mjs";
|
|
26
13
|
import { DefaultBackground } from "./lib/components/default-components/DefaultBackground.mjs";
|
|
27
14
|
import { DefaultBrush } from "./lib/components/default-components/DefaultBrush.mjs";
|
|
28
15
|
import {
|
|
@@ -64,38 +51,45 @@ import {
|
|
|
64
51
|
} from "./lib/components/default-components/DefaultSnapIndictor.mjs";
|
|
65
52
|
import { DefaultSpinner } from "./lib/components/default-components/DefaultSpinner.mjs";
|
|
66
53
|
import { DefaultSvgDefs } from "./lib/components/default-components/DefaultSvgDefs.mjs";
|
|
54
|
+
import {
|
|
55
|
+
ErrorBoundary,
|
|
56
|
+
OptionalErrorBoundary
|
|
57
|
+
} from "./lib/components/ErrorBoundary.mjs";
|
|
58
|
+
import { HTMLContainer } from "./lib/components/HTMLContainer.mjs";
|
|
59
|
+
import { MenuClickCapture } from "./lib/components/MenuClickCapture.mjs";
|
|
60
|
+
import { SVGContainer } from "./lib/components/SVGContainer.mjs";
|
|
61
|
+
import {
|
|
62
|
+
createTLSchemaFromUtils,
|
|
63
|
+
createTLStore,
|
|
64
|
+
inlineBase64AssetStore
|
|
65
|
+
} from "./lib/config/createTLStore.mjs";
|
|
66
|
+
import { createTLUser, useTldrawUser } from "./lib/config/createTLUser.mjs";
|
|
67
|
+
import { coreShapes } from "./lib/config/defaultShapes.mjs";
|
|
67
68
|
import {
|
|
68
69
|
getSnapshot,
|
|
69
70
|
loadSnapshot
|
|
70
71
|
} from "./lib/config/TLEditorSnapshot.mjs";
|
|
71
72
|
import {
|
|
72
|
-
TAB_ID,
|
|
73
73
|
createSessionStateSnapshotSignal,
|
|
74
74
|
extractSessionStateFromLegacySnapshot,
|
|
75
|
-
loadSessionStateSnapshotIntoStore
|
|
75
|
+
loadSessionStateSnapshotIntoStore,
|
|
76
|
+
TAB_ID
|
|
76
77
|
} from "./lib/config/TLSessionStateSnapshot.mjs";
|
|
77
78
|
import {
|
|
78
|
-
USER_COLORS,
|
|
79
79
|
defaultUserPreferences,
|
|
80
80
|
getFreshUserPreferences,
|
|
81
81
|
getUserPreferences,
|
|
82
82
|
setUserPreferences,
|
|
83
|
+
USER_COLORS,
|
|
83
84
|
userTypeValidator
|
|
84
85
|
} from "./lib/config/TLUserPreferences.mjs";
|
|
85
|
-
import {
|
|
86
|
-
createTLSchemaFromUtils,
|
|
87
|
-
createTLStore,
|
|
88
|
-
inlineBase64AssetStore
|
|
89
|
-
} from "./lib/config/createTLStore.mjs";
|
|
90
|
-
import { createTLUser, useTldrawUser } from "./lib/config/createTLUser.mjs";
|
|
91
|
-
import { coreShapes } from "./lib/config/defaultShapes.mjs";
|
|
92
86
|
import { DEFAULT_ANIMATION_OPTIONS, DEFAULT_CAMERA_OPTIONS, SIDES } from "./lib/constants.mjs";
|
|
93
|
-
import {
|
|
94
|
-
Editor
|
|
95
|
-
} from "./lib/editor/Editor.mjs";
|
|
96
87
|
import {
|
|
97
88
|
BindingUtil
|
|
98
89
|
} from "./lib/editor/bindings/BindingUtil.mjs";
|
|
90
|
+
import {
|
|
91
|
+
Editor
|
|
92
|
+
} from "./lib/editor/Editor.mjs";
|
|
99
93
|
import { ClickManager } from "./lib/editor/managers/ClickManager/ClickManager.mjs";
|
|
100
94
|
import { EdgeScrollManager } from "./lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs";
|
|
101
95
|
import {
|
|
@@ -117,10 +111,10 @@ import {
|
|
|
117
111
|
} from "./lib/editor/managers/TextManager/TextManager.mjs";
|
|
118
112
|
import { UserPreferencesManager } from "./lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs";
|
|
119
113
|
import { BaseBoxShapeUtil } from "./lib/editor/shapes/BaseBoxShapeUtil.mjs";
|
|
114
|
+
import { GroupShapeUtil } from "./lib/editor/shapes/group/GroupShapeUtil.mjs";
|
|
120
115
|
import {
|
|
121
116
|
ShapeUtil
|
|
122
117
|
} from "./lib/editor/shapes/ShapeUtil.mjs";
|
|
123
|
-
import { GroupShapeUtil } from "./lib/editor/shapes/group/GroupShapeUtil.mjs";
|
|
124
118
|
import {
|
|
125
119
|
getPerfectDashProps
|
|
126
120
|
} from "./lib/editor/shapes/shared/getPerfectDashProps.mjs";
|
|
@@ -129,13 +123,13 @@ import { resizeScaled } from "./lib/editor/shapes/shared/resizeScaled.mjs";
|
|
|
129
123
|
import { BaseBoxShapeTool } from "./lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs";
|
|
130
124
|
import { maybeSnapToGrid } from "./lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs";
|
|
131
125
|
import { StateNode } from "./lib/editor/tools/StateNode.mjs";
|
|
126
|
+
import {
|
|
127
|
+
EVENT_NAME_MAP
|
|
128
|
+
} from "./lib/editor/types/event-types.mjs";
|
|
132
129
|
import {
|
|
133
130
|
useDelaySvgExport,
|
|
134
131
|
useSvgExportContext
|
|
135
132
|
} from "./lib/editor/types/SvgExportContext.mjs";
|
|
136
|
-
import {
|
|
137
|
-
EVENT_NAME_MAP
|
|
138
|
-
} from "./lib/editor/types/event-types.mjs";
|
|
139
133
|
import { getSvgAsImage } from "./lib/exports/getSvgAsImage.mjs";
|
|
140
134
|
import { tlenv } from "./lib/globals/environment.mjs";
|
|
141
135
|
import { tlmenus } from "./lib/globals/menus.mjs";
|
|
@@ -184,8 +178,6 @@ import {
|
|
|
184
178
|
ROTATE_CORNER_TO_SELECTION_CORNER,
|
|
185
179
|
rotateSelectionHandle
|
|
186
180
|
} from "./lib/primitives/Box.mjs";
|
|
187
|
-
import { Mat } from "./lib/primitives/Mat.mjs";
|
|
188
|
-
import { Vec } from "./lib/primitives/Vec.mjs";
|
|
189
181
|
import { EASINGS } from "./lib/primitives/easings.mjs";
|
|
190
182
|
import { Arc2d } from "./lib/primitives/geometry/Arc2d.mjs";
|
|
191
183
|
import { Circle2d } from "./lib/primitives/geometry/Circle2d.mjs";
|
|
@@ -218,11 +210,8 @@ import {
|
|
|
218
210
|
polygonIntersectsPolyline,
|
|
219
211
|
polygonsIntersect
|
|
220
212
|
} from "./lib/primitives/intersect.mjs";
|
|
213
|
+
import { Mat } from "./lib/primitives/Mat.mjs";
|
|
221
214
|
import {
|
|
222
|
-
HALF_PI,
|
|
223
|
-
PI,
|
|
224
|
-
PI2,
|
|
225
|
-
SIN,
|
|
226
215
|
angleDistance,
|
|
227
216
|
approximately,
|
|
228
217
|
areAnglesCompatible,
|
|
@@ -239,22 +228,29 @@ import {
|
|
|
239
228
|
getPointOnCircle,
|
|
240
229
|
getPointsOnArc,
|
|
241
230
|
getPolygonVertices,
|
|
231
|
+
HALF_PI,
|
|
242
232
|
isSafeFloat,
|
|
243
233
|
perimeterOfEllipse,
|
|
234
|
+
PI,
|
|
235
|
+
PI2,
|
|
244
236
|
pointInPolygon,
|
|
245
237
|
precise,
|
|
246
238
|
radiansToDegrees,
|
|
247
239
|
rangeIntersection,
|
|
248
240
|
shortAngleDist,
|
|
241
|
+
SIN,
|
|
249
242
|
snapAngle,
|
|
250
243
|
toDomPrecision,
|
|
251
244
|
toFixed,
|
|
252
245
|
toPrecision
|
|
253
246
|
} from "./lib/primitives/utils.mjs";
|
|
247
|
+
import { Vec } from "./lib/primitives/Vec.mjs";
|
|
254
248
|
import {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
249
|
+
ErrorScreen,
|
|
250
|
+
LoadingScreen,
|
|
251
|
+
TldrawEditor,
|
|
252
|
+
useOnMount
|
|
253
|
+
} from "./lib/TldrawEditor.mjs";
|
|
258
254
|
import { dataUrlToFile, getDefaultCdnBaseUrl } from "./lib/utils/assets.mjs";
|
|
259
255
|
import { clampToBrowserMaxCanvasSize } from "./lib/utils/browserCanvasMaxSize.mjs";
|
|
260
256
|
import {
|
|
@@ -289,8 +285,12 @@ import {
|
|
|
289
285
|
getRotationSnapshot
|
|
290
286
|
} from "./lib/utils/rotation.mjs";
|
|
291
287
|
import { runtime, setRuntimeOverrides } from "./lib/utils/runtime.mjs";
|
|
292
|
-
import {
|
|
288
|
+
import {
|
|
289
|
+
ReadonlySharedStyleMap,
|
|
290
|
+
SharedStyleMap
|
|
291
|
+
} from "./lib/utils/SharedStylesMap.mjs";
|
|
293
292
|
import { hardReset } from "./lib/utils/sync/hardReset.mjs";
|
|
293
|
+
import { LocalIndexedDb, Table } from "./lib/utils/sync/LocalIndexedDb.mjs";
|
|
294
294
|
import { uniq } from "./lib/utils/uniq.mjs";
|
|
295
295
|
import { openWindow } from "./lib/utils/window-open.mjs";
|
|
296
296
|
function debugEnableLicensing() {
|
|
@@ -298,7 +298,7 @@ function debugEnableLicensing() {
|
|
|
298
298
|
}
|
|
299
299
|
registerTldrawLibraryVersion(
|
|
300
300
|
"@tldraw/editor",
|
|
301
|
-
"3.15.0-canary.
|
|
301
|
+
"3.15.0-canary.c4b9179d0b38",
|
|
302
302
|
"esm"
|
|
303
303
|
);
|
|
304
304
|
export {
|