New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@tldraw/tlsync-client

Package Overview
Dependencies
Maintainers
4
Versions
327
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tldraw/tlsync-client - npm Package Compare versions

Comparing version 2.0.0-canary.e312ea047 to 2.0.0-canary.e3cf05f408a8

116

dist-cjs/index.d.ts

@@ -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 { }

13

dist-cjs/index.js

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc