@tldraw/tlsync-client
Advanced tools
Comparing version 2.0.0-canary.e312ea047 to 2.0.0-canary.e3cf05f408a8
@@ -1,43 +0,12 @@ | ||
import { RecordsDiff } from '@tldraw/tlstore'; | ||
import { SerializedSchema } from '@tldraw/tlstore'; | ||
import { Store } from '@tldraw/tlstore'; | ||
import { StoreSnapshot } from '@tldraw/tlstore'; | ||
import { SyncedStore } from '@tldraw/editor'; | ||
import { TldrawEditorConfig } from '@tldraw/editor'; | ||
import { TLInstanceId } from '@tldraw/editor'; | ||
import { TLRecord } from '@tldraw/editor'; | ||
import { TLStore } from '@tldraw/editor'; | ||
import { TLStoreSchema } from '@tldraw/editor'; | ||
import { TLUser } from '@tldraw/editor'; | ||
import { TLUserId } from '@tldraw/editor'; | ||
/** @public */ | ||
export declare function addDbName(name: string): void; | ||
declare type AnnounceMessage = { | ||
type: 'announce'; | ||
schema: SerializedSchema; | ||
}; | ||
/** @public */ | ||
export declare class BroadcastChannelMock { | ||
onmessage?: (e: MessageEvent) => void; | ||
constructor(_name: string); | ||
postMessage(_msg: Message): void; | ||
close(): void; | ||
} | ||
/** @public */ | ||
export declare function clearDb(universalPersistenceKey: string): void; | ||
/** @public */ | ||
export declare const DEFAULT_DOCUMENT_NAME: any; | ||
/** @public */ | ||
export declare function getAllIndexDbNames(): string[]; | ||
/** @public */ | ||
export declare function getUserData(): TLUser; | ||
/** @public */ | ||
/** | ||
* Clear the database of all data associated with tldraw. | ||
* | ||
* @public */ | ||
export declare function hardReset({ shouldReload }?: { | ||
@@ -48,89 +17,18 @@ shouldReload?: boolean | undefined; | ||
/** @public */ | ||
export declare function loadDataFromStore(universalPersistenceKey: string, opts?: { | ||
didCancel?: () => boolean; | ||
}): Promise<{ | ||
records: TLRecord[]; | ||
schema?: SerializedSchema; | ||
} | undefined>; | ||
declare type Message = AnnounceMessage | SyncMessage; | ||
/** @public */ | ||
export declare const STORE_PREFIX = "TLDRAW_DOCUMENT_v2"; | ||
/** @public */ | ||
export declare function storeChangesInIndexedDb(universalPersistenceKey: string, schema: TLStoreSchema, changes: RecordsDiff<any>, opts?: { | ||
didCancel?: () => boolean; | ||
}): Promise<void>; | ||
/** @public */ | ||
export declare function storeSnapshotInIndexedDb(universalPersistenceKey: string, schema: TLStoreSchema, snapshot: StoreSnapshot<any>, opts?: { | ||
didCancel?: () => boolean; | ||
}): Promise<void>; | ||
/** @public */ | ||
export declare function subscribeToUserData(store: Store<any>): () => void; | ||
/** | ||
* IMPORTANT!!! | ||
* | ||
* This is just a quick-n-dirty temporary solution that will be replaced with the remote sync client | ||
* once it has the db integrated | ||
*/ | ||
declare type SyncMessage = { | ||
type: 'diff'; | ||
instanceId: TLInstanceId; | ||
changes: RecordsDiff<any>; | ||
schema: SerializedSchema; | ||
}; | ||
/** @public */ | ||
export declare const TAB_ID: TLInstanceId; | ||
/** @public */ | ||
export declare class TLLocalSyncClient { | ||
readonly store: TLStore; | ||
readonly channel: BroadcastChannel | BroadcastChannelMock; | ||
private disposables; | ||
private diffQueue; | ||
private didDispose; | ||
private shouldDoFullDBWrite; | ||
private isReloading; | ||
readonly universalPersistenceKey: string; | ||
readonly serializedSchema: SerializedSchema; | ||
private isDebugging; | ||
initTime: number; | ||
private debug; | ||
constructor(store: TLStore, { universalPersistenceKey, onLoad, onLoadError, }: { | ||
universalPersistenceKey: string; | ||
onLoad: (self: TLLocalSyncClient) => void; | ||
onLoadError: (error: Error) => void; | ||
}, channel?: BroadcastChannel | BroadcastChannelMock); | ||
private connect; | ||
close(): void; | ||
private isPersisting; | ||
private didLastWriteError; | ||
private scheduledPersistTimeout; | ||
/* Excluded from this release type: schedulePersist */ | ||
/* Excluded from this release type: persistIfNeeded */ | ||
/** | ||
* Actually persist to indexeddb. If the write fails, then we'll retry with a full db write after | ||
* a short delay. | ||
*/ | ||
private doPersist; | ||
} | ||
/** | ||
* This is a temporary solution that will be replaced with the remote sync client once it has the db | ||
* integrated | ||
* Use a client that persists to indexedDB and syncs to other stores with the same instance id, e.g. other tabs running the same instance of tldraw. | ||
* | ||
* @public | ||
*/ | ||
export declare function useLocalSyncClient({ universalPersistenceKey, instanceId, userId, config, }: { | ||
export declare function useLocalSyncClient({ universalPersistenceKey, instanceId, config, }: { | ||
universalPersistenceKey: string; | ||
instanceId: TLInstanceId; | ||
userId: TLUserId; | ||
config?: TldrawEditorConfig; | ||
config: TldrawEditorConfig; | ||
}): SyncedStore; | ||
export { } |
@@ -18,14 +18,15 @@ "use strict"; | ||
}; | ||
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
var src_exports = {}; | ||
__export(src_exports, { | ||
hardReset: () => import_hardReset.hardReset | ||
DEFAULT_DOCUMENT_NAME: () => import_persistence_constants.DEFAULT_DOCUMENT_NAME, | ||
STORE_PREFIX: () => import_persistence_constants.STORE_PREFIX, | ||
TAB_ID: () => import_persistence_constants.TAB_ID, | ||
hardReset: () => import_hardReset.hardReset, | ||
useLocalSyncClient: () => import_useLocalSyncClient.useLocalSyncClient | ||
}); | ||
module.exports = __toCommonJS(src_exports); | ||
__reExport(src_exports, require("./lib/TLLocalSyncClient"), module.exports); | ||
var import_hardReset = require("./lib/hardReset"); | ||
__reExport(src_exports, require("./lib/hooks/useLocalSyncClient"), module.exports); | ||
__reExport(src_exports, require("./lib/indexedDb"), module.exports); | ||
__reExport(src_exports, require("./lib/persistence-constants"), module.exports); | ||
var import_useLocalSyncClient = require("./lib/hooks/useLocalSyncClient"); | ||
var import_persistence_constants = require("./lib/persistence-constants"); | ||
//# sourceMappingURL=index.js.map |
@@ -27,3 +27,2 @@ "use strict"; | ||
var import_hardReset = require("../hardReset"); | ||
var import_persistence_constants = require("../persistence-constants"); | ||
var import_TLLocalSyncClient = require("../TLLocalSyncClient"); | ||
@@ -33,4 +32,3 @@ function useLocalSyncClient({ | ||
instanceId, | ||
userId, | ||
config = import_editor.TldrawEditorConfig.default | ||
config | ||
}) { | ||
@@ -52,3 +50,3 @@ const [state, setState] = (0, import_react.useState)(null); | ||
}; | ||
const store = config.createStore({ userId, instanceId }); | ||
const store = config.createStore({ instanceId }); | ||
const client = new import_TLLocalSyncClient.TLLocalSyncClient(store, { | ||
@@ -63,11 +61,9 @@ universalPersistenceKey, | ||
}); | ||
const userDataUnsubcribe = (0, import_persistence_constants.subscribeToUserData)(store); | ||
return () => { | ||
setState((prevState) => prevState?.id === id ? null : prevState); | ||
userDataUnsubcribe(); | ||
client.close(); | ||
}; | ||
}, [instanceId, universalPersistenceKey, config, userId]); | ||
}, [instanceId, universalPersistenceKey, config]); | ||
return state?.syncedStore ?? { status: "loading" }; | ||
} | ||
//# sourceMappingURL=useLocalSyncClient.js.map |
@@ -25,9 +25,6 @@ "use strict"; | ||
addDbName: () => addDbName, | ||
getAllIndexDbNames: () => getAllIndexDbNames, | ||
getUserData: () => getUserData, | ||
subscribeToUserData: () => subscribeToUserData | ||
getAllIndexDbNames: () => getAllIndexDbNames | ||
}); | ||
module.exports = __toCommonJS(persistence_constants_exports); | ||
var import_editor = require("@tldraw/editor"); | ||
var import_signia = require("signia"); | ||
const tabIdKey = "TLDRAW_TAB_ID_v2"; | ||
@@ -43,30 +40,2 @@ const window = globalThis.window; | ||
} | ||
const USER_DATA_KEY = "TLDRAW_USER_DATA_v2"; | ||
const globalUserData = (0, import_signia.atom)( | ||
"globalUserData", | ||
JSON.parse(window?.localStorage.getItem(USER_DATA_KEY) || "null") ?? import_editor.TLUser.create({}) | ||
); | ||
(0, import_signia.react)("set global user data", () => { | ||
if (window) { | ||
window.localStorage.setItem(USER_DATA_KEY, JSON.stringify(globalUserData.value)); | ||
} | ||
}); | ||
function getUserData() { | ||
return globalUserData.value; | ||
} | ||
function subscribeToUserData(store) { | ||
const userId = globalUserData.value.id; | ||
return store.listen(({ changes }) => { | ||
for (const record of Object.values(changes.added)) { | ||
if (record.typeName === "user" && userId === record.id) { | ||
globalUserData.set(record); | ||
} | ||
} | ||
for (const [_, record] of Object.values(changes.updated)) { | ||
if (record.typeName === "user" && userId === record.id) { | ||
globalUserData.set(record); | ||
} | ||
} | ||
}); | ||
} | ||
const defaultDocumentKey = "TLDRAW_DEFAULT_DOCUMENT_NAME_v2"; | ||
@@ -76,3 +45,3 @@ const DEFAULT_DOCUMENT_NAME = window?.localStorage.getItem(defaultDocumentKey) ?? (0, import_editor.uniqueId)(); | ||
const STORE_PREFIX = "TLDRAW_DOCUMENT_v2"; | ||
const TAB_ID = window?.[tabIdKey] ?? window?.sessionStorage[tabIdKey] ?? import_editor.TLInstance.createId(); | ||
const TAB_ID = window?.[tabIdKey] ?? window?.sessionStorage[tabIdKey] ?? import_editor.InstanceRecordType.createId(); | ||
if (window) { | ||
@@ -79,0 +48,0 @@ window[tabIdKey] = TAB_ID; |
@@ -123,3 +123,8 @@ "use strict"; | ||
this.store.mergeRemoteChanges(() => { | ||
this.store.put(Object.values(migrationResult.value), "initialize"); | ||
this.store.put( | ||
Object.values(migrationResult.value).filter( | ||
(r) => this.store.schema.types[r.typeName].scope !== "presence" | ||
), | ||
"initialize" | ||
); | ||
}); | ||
@@ -126,0 +131,0 @@ } |
{ | ||
"name": "@tldraw/tlsync-client", | ||
"description": "A tiny little drawing app (multiplayer sync).", | ||
"version": "2.0.0-canary.e312ea047", | ||
"version": "2.0.0-canary.e3cf05f408a8", | ||
"packageManager": "yarn@3.5.0", | ||
"author": { | ||
@@ -34,9 +35,9 @@ "name": "tldraw GB Ltd.", | ||
"scripts": { | ||
"test": "yarn run -T jest", | ||
"test:coverage": "yarn run -T jest --coverage", | ||
"build": "echo 'build should be run by turbo'", | ||
"build:package": "yarn run -T tsx ../../scripts/build-package.ts", | ||
"build:api": "yarn run -T tsx ../../scripts/build-api.ts", | ||
"test": "lazy inherit", | ||
"test-coverage": "lazy inherit", | ||
"build": "yarn run -T tsx ../../scripts/build-package.ts", | ||
"build-api": "yarn run -T tsx ../../scripts/build-api.ts", | ||
"prepack": "yarn run -T tsx ../../scripts/prepack.ts", | ||
"postpack": "../../scripts/postpack.sh", | ||
"pack-tarball": "yarn pack", | ||
"lint": "yarn run -T tsx ../../scripts/lint.ts" | ||
@@ -47,2 +48,3 @@ }, | ||
"@types/react-dom": "*", | ||
"lazyrepo": "0.0.0-alpha.26", | ||
"ws": "^8.10.0" | ||
@@ -71,4 +73,5 @@ }, | ||
"dependencies": { | ||
"@tldraw/editor": "2.0.0-canary.e312ea047", | ||
"@tldraw/tlstore": "2.0.0-canary.e312ea047", | ||
"@tldraw/editor": "2.0.0-canary.e3cf05f408a8", | ||
"@tldraw/tlstore": "2.0.0-canary.e3cf05f408a8", | ||
"@tldraw/utils": "2.0.0-canary.e3cf05f408a8", | ||
"idb": "^7.1.0" | ||
@@ -75,0 +78,0 @@ }, |
# @tldraw/tlsync-client | ||
## License | ||
The source code in this repository (as well as our 2.0+ distributions and releases) are currently licensed under Apache-2.0. These licenses are subject to change in our upcoming 2.0 release. If you are planning to use tldraw in a commercial product, please reach out at [hello@tldraw.com](mailto://hello@tldraw.com). |
@@ -1,5 +0,3 @@ | ||
export * from './lib/TLLocalSyncClient' | ||
export { hardReset } from './lib/hardReset' | ||
export * from './lib/hooks/useLocalSyncClient' | ||
export * from './lib/indexedDb' | ||
export * from './lib/persistence-constants' | ||
export { useLocalSyncClient } from './lib/hooks/useLocalSyncClient' | ||
export { DEFAULT_DOCUMENT_NAME, STORE_PREFIX, TAB_ID } from './lib/persistence-constants' |
@@ -1,2 +0,2 @@ | ||
/** @public */ | ||
/** @internal */ | ||
export function showCantWriteToIndexDbAlert() { | ||
@@ -12,3 +12,3 @@ window.alert( | ||
/** @public */ | ||
/** @internal */ | ||
export function showCantReadFromIndexDbAlert() { | ||
@@ -15,0 +15,0 @@ window.alert( |
import { deleteDB } from 'idb' | ||
import { getAllIndexDbNames } from './persistence-constants' | ||
/** @public */ | ||
/** | ||
* Clear the database of all data associated with tldraw. | ||
* | ||
* @public */ | ||
export async function hardReset({ shouldReload = true } = {}) { | ||
@@ -6,0 +9,0 @@ sessionStorage.clear() |
@@ -1,10 +0,8 @@ | ||
import { SyncedStore, TldrawEditorConfig, TLInstanceId, TLUserId, uniqueId } from '@tldraw/editor' | ||
import { SyncedStore, TldrawEditorConfig, TLInstanceId, uniqueId } from '@tldraw/editor' | ||
import { useEffect, useState } from 'react' | ||
import '../hardReset' | ||
import { subscribeToUserData } from '../persistence-constants' | ||
import { TLLocalSyncClient } from '../TLLocalSyncClient' | ||
/** | ||
* This is a temporary solution that will be replaced with the remote sync client once it has the db | ||
* integrated | ||
* Use a client that persists to indexedDB and syncs to other stores with the same instance id, e.g. other tabs running the same instance of tldraw. | ||
* | ||
@@ -16,9 +14,7 @@ * @public | ||
instanceId, | ||
userId, | ||
config = TldrawEditorConfig.default, | ||
config, | ||
}: { | ||
universalPersistenceKey: string | ||
instanceId: TLInstanceId | ||
userId: TLUserId | ||
config?: TldrawEditorConfig | ||
config: TldrawEditorConfig | ||
}): SyncedStore { | ||
@@ -42,3 +38,3 @@ const [state, setState] = useState<{ id: string; syncedStore: SyncedStore } | null>(null) | ||
const store = config.createStore({ userId, instanceId }) | ||
const store = config.createStore({ instanceId }) | ||
@@ -55,12 +51,9 @@ const client = new TLLocalSyncClient(store, { | ||
const userDataUnsubcribe = subscribeToUserData(store) | ||
return () => { | ||
setState((prevState) => (prevState?.id === id ? null : prevState)) | ||
userDataUnsubcribe() | ||
client.close() | ||
} | ||
}, [instanceId, universalPersistenceKey, config, userId]) | ||
}, [instanceId, universalPersistenceKey, config]) | ||
return state?.syncedStore ?? { status: 'loading' } | ||
} |
@@ -23,3 +23,3 @@ import { TLRecord, TLStoreSchema } from '@tldraw/editor' | ||
/** @public */ | ||
/** @internal */ | ||
export async function loadDataFromStore( | ||
@@ -45,3 +45,3 @@ universalPersistenceKey: string, | ||
/** @public */ | ||
/** @internal */ | ||
export async function storeChangesInIndexedDb( | ||
@@ -81,3 +81,3 @@ universalPersistenceKey: string, | ||
/** @public */ | ||
/** @internal */ | ||
export async function storeSnapshotInIndexedDb( | ||
@@ -111,3 +111,3 @@ universalPersistenceKey: string, | ||
/** @public */ | ||
/** @internal */ | ||
export function clearDb(universalPersistenceKey: string) { | ||
@@ -114,0 +114,0 @@ const dbId = STORE_PREFIX + universalPersistenceKey |
@@ -1,4 +0,2 @@ | ||
import { TLInstance, TLInstanceId, TLUser, uniqueId } from '@tldraw/editor' | ||
import { Store } from '@tldraw/tlstore' | ||
import { atom, react } from 'signia' | ||
import { InstanceRecordType, TLInstanceId, uniqueId } from '@tldraw/editor' | ||
@@ -29,41 +27,6 @@ const tabIdKey = 'TLDRAW_TAB_ID_v2' as const | ||
// the id of the user, stored in localStorage so that it persists across sessions | ||
const USER_DATA_KEY = 'TLDRAW_USER_DATA_v2' | ||
const globalUserData = atom<TLUser>( | ||
'globalUserData', | ||
JSON.parse(window?.localStorage.getItem(USER_DATA_KEY) || 'null') ?? TLUser.create({}) | ||
) | ||
react('set global user data', () => { | ||
if (window) { | ||
window.localStorage.setItem(USER_DATA_KEY, JSON.stringify(globalUserData.value)) | ||
} | ||
}) | ||
/** @public */ | ||
export function getUserData() { | ||
return globalUserData.value | ||
} | ||
/** @public */ | ||
export function subscribeToUserData(store: Store<any>) { | ||
const userId = globalUserData.value.id | ||
return store.listen(({ changes }) => { | ||
for (const record of Object.values(changes.added)) { | ||
if (record.typeName === 'user' && userId === record.id) { | ||
globalUserData.set(record) | ||
} | ||
} | ||
for (const [_, record] of Object.values(changes.updated)) { | ||
if (record.typeName === 'user' && userId === record.id) { | ||
globalUserData.set(record) | ||
} | ||
} | ||
}) | ||
} | ||
// the id of the document that will be loaded if the URL doesn't contain a document id | ||
// again, stored in localStorage | ||
const defaultDocumentKey = 'TLDRAW_DEFAULT_DOCUMENT_NAME_v2' | ||
/** @public */ | ||
@@ -80,3 +43,3 @@ export const DEFAULT_DOCUMENT_NAME = | ||
export const TAB_ID: TLInstanceId = | ||
window?.[tabIdKey] ?? window?.sessionStorage[tabIdKey] ?? TLInstance.createId() | ||
window?.[tabIdKey] ?? window?.sessionStorage[tabIdKey] ?? InstanceRecordType.createId() | ||
if (window) { | ||
@@ -102,3 +65,3 @@ window[tabIdKey] = TAB_ID | ||
/** @public */ | ||
/** @internal */ | ||
export function getAllIndexDbNames(): string[] { | ||
@@ -112,3 +75,3 @@ const result = JSON.parse(window?.localStorage.getItem(dbNameIndexKey) || '[]') ?? [] | ||
/** @public */ | ||
/** @internal */ | ||
export function addDbName(name: string) { | ||
@@ -115,0 +78,0 @@ const all = new Set(getAllIndexDbNames()) |
import { | ||
InstanceRecordType, | ||
PageRecordType, | ||
TldrawEditorConfig, | ||
TLInstance, | ||
TLInstanceId, | ||
TLPage, | ||
TLUser, | ||
TLUserId, | ||
} from '@tldraw/editor' | ||
@@ -33,8 +31,6 @@ import { promiseWithResolve } from '@tldraw/utils' | ||
function testClient( | ||
instanceId: TLInstanceId = TLInstance.createCustomId('test'), | ||
userId: TLUserId = TLUser.createCustomId('test'), | ||
instanceId: TLInstanceId = InstanceRecordType.createCustomId('test'), | ||
channel = new BroadcastChannelMock('test') | ||
) { | ||
const store = TldrawEditorConfig.default.createStore({ | ||
userId, | ||
const store = new TldrawEditorConfig().createStore({ | ||
instanceId, | ||
@@ -89,3 +85,3 @@ }) | ||
test('when a client receives an annouce with a newer schema version it reloads itself', async () => { | ||
test('when a client receives an announce with a newer schema version it reloads itself', async () => { | ||
const { client, channel, onLoadError } = testClient() | ||
@@ -108,3 +104,3 @@ await tick() | ||
test('when a client receives an annouce with a newer schema version shortly after loading it does not reload but instead reports a loadError', async () => { | ||
test('when a client receives an announce with a newer schema version shortly after loading it does not reload but instead reports a loadError', async () => { | ||
const { client, channel, onLoadError } = testClient() | ||
@@ -130,3 +126,3 @@ await tick() | ||
await tick() | ||
client.store.put([TLPage.create({ name: 'test', index: 'a0' })]) | ||
client.store.put([PageRecordType.create({ name: 'test', index: 'a0' })]) | ||
await tick() | ||
@@ -136,3 +132,3 @@ expect(idb.storeSnapshotInIndexedDb).toHaveBeenCalledTimes(1) | ||
client.store.put([TLPage.create({ name: 'test2', index: 'a1' })]) | ||
client.store.put([PageRecordType.create({ name: 'test2', index: 'a1' })]) | ||
await tick() | ||
@@ -146,3 +142,3 @@ expect(idb.storeSnapshotInIndexedDb).toHaveBeenCalledTimes(1) | ||
await tick() | ||
client.store.put([TLPage.create({ name: 'test', index: 'a0' })]) | ||
client.store.put([PageRecordType.create({ name: 'test', index: 'a0' })]) | ||
await tick() | ||
@@ -152,3 +148,3 @@ // @ts-expect-error | ||
client.store.put([TLPage.create({ name: 'test2', index: 'a1' })]) | ||
client.store.put([PageRecordType.create({ name: 'test2', index: 'a1' })]) | ||
await tick() | ||
@@ -165,3 +161,3 @@ // @ts-expect-error | ||
await tick() | ||
client.store.put([TLPage.create({ name: 'test', index: 'a0' })]) | ||
client.store.put([PageRecordType.create({ name: 'test', index: 'a0' })]) | ||
await tick() | ||
@@ -174,3 +170,3 @@ | ||
// if another change comes in, loads of time can pass, but nothing else should get called | ||
client.store.put([TLPage.create({ name: 'test', index: 'a2' })]) | ||
client.store.put([PageRecordType.create({ name: 'test', index: 'a2' })]) | ||
await tick() | ||
@@ -177,0 +173,0 @@ expect(idb.storeSnapshotInIndexedDb).toHaveBeenCalledTimes(1) |
@@ -39,3 +39,3 @@ import { TLInstanceId, TLRecord, TLStore } from '@tldraw/editor' | ||
/** @public */ | ||
/** @internal */ | ||
export class BroadcastChannelMock { | ||
@@ -56,3 +56,3 @@ onmessage?: (e: MessageEvent) => void | ||
/** @public */ | ||
/** @internal */ | ||
export class TLLocalSyncClient { | ||
@@ -160,3 +160,8 @@ private disposables = new Set<() => void>() | ||
// Calling put will validate the records! | ||
this.store.put(Object.values(migrationResult.value), 'initialize') | ||
this.store.put( | ||
Object.values(migrationResult.value).filter( | ||
(r) => this.store.schema.types[r.typeName].scope !== 'presence' | ||
), | ||
'initialize' | ||
) | ||
}) | ||
@@ -163,0 +168,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
6
145870
7
4
1868
+ Added@tldraw/editor@2.0.0-canary.e3cf05f408a8(transitive)
+ Added@tldraw/indices@2.0.0-canary.e3cf05f408a8(transitive)
+ Added@tldraw/primitives@2.0.0-canary.e3cf05f408a8(transitive)
+ Added@tldraw/tlschema@2.0.0-canary.e3cf05f408a8(transitive)
+ Added@tldraw/tlstore@2.0.0-canary.e3cf05f408a8(transitive)
+ Added@tldraw/tlvalidate@2.0.0-canary.e3cf05f408a8(transitive)
+ Added@tldraw/utils@2.0.0-canary.e3cf05f408a8(transitive)
+ Addedcrc@4.3.2(transitive)
+ Addednanoid@4.0.2(transitive)
- Removed@tldraw/editor@2.0.0-canary.e312ea047(transitive)
- Removed@tldraw/primitives@2.0.0-canary.e312ea047(transitive)
- Removed@tldraw/tlschema@2.0.0-canary.e312ea047(transitive)
- Removed@tldraw/tlstore@2.0.0-canary.e312ea047(transitive)
- Removed@tldraw/tlvalidate@2.0.0-canary.e312ea047(transitive)
- Removed@tldraw/utils@2.0.0-canary.e312ea047(transitive)
- Removednanoid@3.3.8(transitive)