You're Invited: Meet the Socket team at BSidesSF and RSAC - April 27 - May 1.RSVP
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

to
0.1.0-alpha.7

1

dist/cjs/index.js

@@ -25,3 +25,2 @@ "use strict";

module.exports = __toCommonJS(src_exports);
__reExport(src_exports, require("./lib/alerts"), module.exports);
var import_hardReset = require("./lib/hardReset");

@@ -28,0 +27,0 @@ __reExport(src_exports, require("./lib/hooks/useLocalSyncClient"), module.exports);

11

dist/cjs/lib/hooks/useLocalSyncClient.js

@@ -31,3 +31,6 @@ "use strict";

universalPersistenceKey,
instanceId
instanceId,
userId,
config = import_tldraw_beta.TldrawConfig.default,
initialDataRef
}) {

@@ -49,5 +52,7 @@ const [state, setState] = (0, import_react.useState)(null);

};
const store = new import_tldraw_beta.TLStore();
const initialData = initialDataRef?.current;
const store = initialData ? config.createStore({ initialData }) : config.createStore();
const client = new import_TLLocalSyncClient.TLLocalSyncClient(store, {
instanceId,
userId,
universalPersistenceKey,

@@ -67,5 +72,5 @@ onLoad() {

};
}, [instanceId, universalPersistenceKey]);
}, [instanceId, universalPersistenceKey, initialDataRef, config, userId]);
return state?.syncedStore ?? { status: "loading" };
}
//# sourceMappingURL=useLocalSyncClient.js.map

@@ -28,3 +28,2 @@ "use strict";

var import_tldraw_beta = require("@tldraw/tldraw-beta");
var import_tlschema = require("@tldraw/tlschema");
var import_tlsync = require("@tldraw/tlsync");

@@ -35,6 +34,4 @@ var import_utils = require("@tldraw/utils");

var import_signia_react = require("signia-react");
var import_alerts = require("../alerts");
var import_ClientWebSocketAdapter = require("../ClientWebSocketAdapter");
var import_hardReset = require("../hardReset");
var import_indexedDb = require("../indexedDb");
var import_persistence_constants = require("../persistence-constants");

@@ -51,3 +48,5 @@ class RemoteSyncError extends Error {

roomId = "default",
instanceId
instanceId,
config = import_tldraw_beta.TldrawConfig.default,
snapshotForNewRoomRef
}) {

@@ -66,37 +65,17 @@ const [state, setState] = (0, import_react.useState)(null);

};
const store = new import_tlschema.TLStore();
const store = config.createStore();
const socket = new import_ClientWebSocketAdapter.ClientWebSocketAdapter(uri);
const client = new import_tlsync.TLSyncClient({
store,
schema: import_tlschema.schema,
socket,
instanceId,
async onLoad(client2) {
let json = void 0;
try {
json = await (0, import_indexedDb.loadDataFromStore)("stash");
} catch (error) {
console.error(error);
this.onLoadError(error);
(0, import_alerts.showCantReadFromIndexDbAlert)();
window.location.reload();
return;
const snapshotForNewRoom = snapshotForNewRoomRef?.current;
if (snapshotForNewRoom) {
snapshotForNewRoomRef.current = null;
(0, import_signia.transact)(() => {
client2.store.clear();
client2.store.put((0, import_utils.objectMapValues)(snapshotForNewRoom));
});
}
if (json && json.records.length > 0) {
const { records, schema: serializedSchema } = json;
try {
(0, import_indexedDb.clearDb)("stash");
(0, import_signia.transact)(() => {
const bstore = new import_tlschema.TLStore({
initialData: Object.fromEntries(records.map((r) => [r.id, r])),
UNSAFE_SKIP_INITIAL_VALIDATION: true
});
import_tlschema.schema.migrateStore(bstore, serializedSchema);
client2.store.clear();
client2.store.put(bstore.allRecords(), "initialize");
});
} catch (err) {
console.error(err);
}
}
setCurrentState({ readyClient: client2 });

@@ -122,3 +101,3 @@ },

};
}, [uri, instanceId, roomId]);
}, [uri, instanceId, roomId, snapshotForNewRoomRef, config]);
return (0, import_signia_react.useValue)(

@@ -125,0 +104,0 @@ "remote synced store",

@@ -27,3 +27,2 @@ "use strict";

module.exports = __toCommonJS(indexedDb_exports);
var import_tldraw_beta = require("@tldraw/tldraw-beta");
var import_idb = require("idb");

@@ -47,3 +46,3 @@ var import_persistence_constants = require("./persistence-constants");

}
async function loadDataFromStore(universalPersistenceKey, opts) {
async function loadDataFromStore(universalPersistenceKey, schema, opts) {
const storeId = import_persistence_constants.STORE_PREFIX + universalPersistenceKey;

@@ -60,7 +59,7 @@ if (!(0, import_persistence_constants.getAllIndexDbNames)().includes(storeId))

records: await recordsStore.getAll(),
schema: await schemaStore.get("schema") ?? import_tldraw_beta.schema.serializeEarliestVersion()
schema: await schemaStore.get("schema") ?? schema.serializeEarliestVersion()
};
});
}
async function storeChangesInIndexedDb(universalPersistenceKey, changes, opts) {
async function storeChangesInIndexedDb(universalPersistenceKey, schema, changes, opts) {
const storeId = import_persistence_constants.STORE_PREFIX + universalPersistenceKey;

@@ -80,3 +79,3 @@ await withDb(storeId, async (db) => {

}
schemaStore.put(import_tldraw_beta.schema.serialize(), "schema");
schemaStore.put(schema.serialize(), "schema");
if (opts?.didCancel?.())

@@ -87,3 +86,3 @@ return tx.abort();

}
async function storeSnapshotInIndexedDb(universalPersistenceKey, snapshot, opts) {
async function storeSnapshotInIndexedDb(universalPersistenceKey, schema, snapshot, opts) {
const storeId = import_persistence_constants.STORE_PREFIX + universalPersistenceKey;

@@ -98,3 +97,3 @@ await withDb(storeId, async (db) => {

}
schemaStore.put(import_tldraw_beta.schema.serialize(), "schema");
schemaStore.put(schema.serialize(), "schema");
if (opts?.didCancel?.())

@@ -101,0 +100,0 @@ return tx.abort();

@@ -28,2 +28,3 @@ "use strict";

var import_utils = require("@tldraw/utils");
var import_signia = require("signia");
var import_alerts = require("./alerts");

@@ -47,2 +48,3 @@ var import_indexedDb = require("./indexedDb");

instanceId,
userId,
universalPersistenceKey,

@@ -59,3 +61,5 @@ onLoad,

this.instanceId = instanceId;
this.userId = userId;
this.universalPersistenceKey = universalPersistenceKey;
this.serializedSchema = this.store.schema.serialize();
this.disposables.add(

@@ -86,4 +90,5 @@ store.listen(({ changes, source }) => {

instanceId;
userId;
universalPersistenceKey;
serializedSchema = import_tldraw_beta.schema.serialize();
serializedSchema;
isDebugging = false;

@@ -100,3 +105,3 @@ initTime = Date.now();

try {
data = await (0, import_indexedDb.loadDataFromStore)(this.universalPersistenceKey);
data = await (0, import_indexedDb.loadDataFromStore)(this.universalPersistenceKey, this.store.schema);
} catch (error) {

@@ -116,6 +121,7 @@ onLoadError(error);

const bstore = new import_tldraw_beta.TLStore({
schema: this.store.schema,
initialData: Object.fromEntries(data.records.map((r) => [r.id, r])),
UNSAFE_SKIP_INITIAL_VALIDATION: true
});
const result = import_tldraw_beta.schema.migrateStore(bstore, data.schema);
const result = this.store.schema.migrateStore(bstore, data.schema);
if (result.type === "error") {

@@ -135,3 +141,3 @@ console.error("failed to migrate store", result);

this.serializedSchema,
msg2.schema ?? import_tldraw_beta.schema.serializeEarliestVersion()
msg2.schema ?? this.store.schema.serializeEarliestVersion()
);

@@ -157,4 +163,13 @@ if (comparison === -1) {

this.debug("applying diff");
this.store.mergeRemoteChanges(() => {
this.store.applyDiff(msg2.changes);
const doesDeleteInstance = (0, import_utils.hasOwnProperty)(msg2.changes.removed, this.instanceId);
(0, import_signia.transact)(() => {
this.store.mergeRemoteChanges(() => {
this.store.applyDiff(msg2.changes);
});
if (doesDeleteInstance) {
this.store.ensureStoreIsUsable({
instanceId: this.instanceId,
currentUserId: this.userId
});
}
});

@@ -201,3 +216,4 @@ }

shouldDoFullDBWrite: this.shouldDoFullDBWrite,
diffQueueLength: this.diffQueue.length
diffQueueLength: this.diffQueue.length,
storeIsPossiblyCorrupt: this.store.isPossiblyCorrupted()
});

@@ -212,2 +228,4 @@ if (this.scheduledPersistTimeout) {

return;
if (this.store.isPossiblyCorrupted())
return;
if (this.shouldDoFullDBWrite || this.diffQueue.length > 0) {

@@ -226,8 +244,13 @@ this.doPersist();

this.shouldDoFullDBWrite = false;
await (0, import_indexedDb.storeSnapshotInIndexedDb)(this.universalPersistenceKey, this.store.serialize(), {
didCancel: () => this.didDispose
});
await (0, import_indexedDb.storeSnapshotInIndexedDb)(
this.universalPersistenceKey,
this.store.schema,
this.store.serialize(),
{
didCancel: () => this.didDispose
}
);
} else {
const diffs = (0, import_tlstore.squashRecordDiffs)(diffQueue);
await (0, import_indexedDb.storeChangesInIndexedDb)(this.universalPersistenceKey, diffs);
await (0, import_indexedDb.storeChangesInIndexedDb)(this.universalPersistenceKey, this.store.schema, diffs);
}

@@ -234,0 +257,0 @@ this.didLastWriteError = false;

@@ -1,2 +0,1 @@

export * from "./lib/alerts";
import { hardReset } from "./lib/hardReset";

@@ -3,0 +2,0 @@ export * from "./lib/hooks/useLocalSyncClient";

@@ -1,2 +0,5 @@

import { TLStore, uniqueId } from "@tldraw/tldraw-beta";
import {
TldrawConfig,
uniqueId
} from "@tldraw/tldraw-beta";
import { useEffect, useState } from "react";

@@ -8,3 +11,6 @@ import "../hardReset";

universalPersistenceKey,
instanceId
instanceId,
userId,
config = TldrawConfig.default,
initialDataRef
}) {

@@ -26,5 +32,7 @@ const [state, setState] = useState(null);

};
const store = new TLStore();
const initialData = initialDataRef?.current;
const store = initialData ? config.createStore({ initialData }) : config.createStore();
const client = new TLLocalSyncClient(store, {
instanceId,
userId,
universalPersistenceKey,

@@ -44,3 +52,3 @@ onLoad() {

};
}, [instanceId, universalPersistenceKey]);
}, [instanceId, universalPersistenceKey, initialDataRef, config, userId]);
return state?.syncedStore ?? { status: "loading" };

@@ -47,0 +55,0 @@ }

import { jsx } from "react/jsx-runtime";
import { uniqueId } from "@tldraw/tldraw-beta";
import { schema, TLStore } from "@tldraw/tlschema";
import { TldrawConfig, uniqueId } from "@tldraw/tldraw-beta";
import { TLSyncClient } from "@tldraw/tlsync";
import { exhaustiveSwitchError } from "@tldraw/utils";
import { exhaustiveSwitchError, objectMapValues } from "@tldraw/utils";
import { useEffect, useState } from "react";
import { transact } from "signia";
import { useValue } from "signia-react";
import { showCantReadFromIndexDbAlert } from "../alerts";
import { ClientWebSocketAdapter } from "../ClientWebSocketAdapter";
import "../hardReset";
import { clearDb, loadDataFromStore } from "../indexedDb";
import { getUserData, subscribeToUserData } from "../persistence-constants";

@@ -24,3 +21,5 @@ class RemoteSyncError extends Error {

roomId = "default",
instanceId
instanceId,
config = TldrawConfig.default,
snapshotForNewRoomRef
}) {

@@ -39,37 +38,17 @@ const [state, setState] = useState(null);

};
const store = new TLStore();
const store = config.createStore();
const socket = new ClientWebSocketAdapter(uri);
const client = new TLSyncClient({
store,
schema,
socket,
instanceId,
async onLoad(client2) {
let json = void 0;
try {
json = await loadDataFromStore("stash");
} catch (error) {
console.error(error);
this.onLoadError(error);
showCantReadFromIndexDbAlert();
window.location.reload();
return;
const snapshotForNewRoom = snapshotForNewRoomRef?.current;
if (snapshotForNewRoom) {
snapshotForNewRoomRef.current = null;
transact(() => {
client2.store.clear();
client2.store.put(objectMapValues(snapshotForNewRoom));
});
}
if (json && json.records.length > 0) {
const { records, schema: serializedSchema } = json;
try {
clearDb("stash");
transact(() => {
const bstore = new TLStore({
initialData: Object.fromEntries(records.map((r) => [r.id, r])),
UNSAFE_SKIP_INITIAL_VALIDATION: true
});
schema.migrateStore(bstore, serializedSchema);
client2.store.clear();
client2.store.put(bstore.allRecords(), "initialize");
});
} catch (err) {
console.error(err);
}
}
setCurrentState({ readyClient: client2 });

@@ -95,3 +74,3 @@ },

};
}, [uri, instanceId, roomId]);
}, [uri, instanceId, roomId, snapshotForNewRoomRef, config]);
return useValue(

@@ -98,0 +77,0 @@ "remote synced store",

@@ -1,2 +0,1 @@

import { schema } from "@tldraw/tldraw-beta";
import { openDB } from "idb";

@@ -20,3 +19,3 @@ import { addDbName, getAllIndexDbNames, STORE_PREFIX } from "./persistence-constants";

}
async function loadDataFromStore(universalPersistenceKey, opts) {
async function loadDataFromStore(universalPersistenceKey, schema, opts) {
const storeId = STORE_PREFIX + universalPersistenceKey;

@@ -37,3 +36,3 @@ if (!getAllIndexDbNames().includes(storeId))

}
async function storeChangesInIndexedDb(universalPersistenceKey, changes, opts) {
async function storeChangesInIndexedDb(universalPersistenceKey, schema, changes, opts) {
const storeId = STORE_PREFIX + universalPersistenceKey;

@@ -59,3 +58,3 @@ await withDb(storeId, async (db) => {

}
async function storeSnapshotInIndexedDb(universalPersistenceKey, snapshot, opts) {
async function storeSnapshotInIndexedDb(universalPersistenceKey, schema, snapshot, opts) {
const storeId = STORE_PREFIX + universalPersistenceKey;

@@ -62,0 +61,0 @@ await withDb(storeId, async (db) => {

@@ -1,7 +0,5 @@

import { schema, TLStore } from "@tldraw/tldraw-beta";
import {
compareSchemas,
squashRecordDiffs
} from "@tldraw/tlstore";
import { assert } from "@tldraw/utils";
import { TLStore } from "@tldraw/tldraw-beta";
import { compareSchemas, squashRecordDiffs } from "@tldraw/tlstore";
import { assert, hasOwnProperty } from "@tldraw/utils";
import { transact } from "signia";
import { showCantReadFromIndexDbAlert, showCantWriteToIndexDbAlert } from "./alerts";

@@ -25,2 +23,3 @@ import { loadDataFromStore, storeChangesInIndexedDb, storeSnapshotInIndexedDb } from "./indexedDb";

instanceId,
userId,
universalPersistenceKey,

@@ -37,3 +36,5 @@ onLoad,

this.instanceId = instanceId;
this.userId = userId;
this.universalPersistenceKey = universalPersistenceKey;
this.serializedSchema = this.store.schema.serialize();
this.disposables.add(

@@ -64,4 +65,5 @@ store.listen(({ changes, source }) => {

instanceId;
userId;
universalPersistenceKey;
serializedSchema = schema.serialize();
serializedSchema;
isDebugging = false;

@@ -78,3 +80,3 @@ initTime = Date.now();

try {
data = await loadDataFromStore(this.universalPersistenceKey);
data = await loadDataFromStore(this.universalPersistenceKey, this.store.schema);
} catch (error) {

@@ -94,6 +96,7 @@ onLoadError(error);

const bstore = new TLStore({
schema: this.store.schema,
initialData: Object.fromEntries(data.records.map((r) => [r.id, r])),
UNSAFE_SKIP_INITIAL_VALIDATION: true
});
const result = schema.migrateStore(bstore, data.schema);
const result = this.store.schema.migrateStore(bstore, data.schema);
if (result.type === "error") {

@@ -113,3 +116,3 @@ console.error("failed to migrate store", result);

this.serializedSchema,
msg2.schema ?? schema.serializeEarliestVersion()
msg2.schema ?? this.store.schema.serializeEarliestVersion()
);

@@ -135,4 +138,13 @@ if (comparison === -1) {

this.debug("applying diff");
this.store.mergeRemoteChanges(() => {
this.store.applyDiff(msg2.changes);
const doesDeleteInstance = hasOwnProperty(msg2.changes.removed, this.instanceId);
transact(() => {
this.store.mergeRemoteChanges(() => {
this.store.applyDiff(msg2.changes);
});
if (doesDeleteInstance) {
this.store.ensureStoreIsUsable({
instanceId: this.instanceId,
currentUserId: this.userId
});
}
});

@@ -179,3 +191,4 @@ }

shouldDoFullDBWrite: this.shouldDoFullDBWrite,
diffQueueLength: this.diffQueue.length
diffQueueLength: this.diffQueue.length,
storeIsPossiblyCorrupt: this.store.isPossiblyCorrupted()
});

@@ -190,2 +203,4 @@ if (this.scheduledPersistTimeout) {

return;
if (this.store.isPossiblyCorrupted())
return;
if (this.shouldDoFullDBWrite || this.diffQueue.length > 0) {

@@ -204,8 +219,13 @@ this.doPersist();

this.shouldDoFullDBWrite = false;
await storeSnapshotInIndexedDb(this.universalPersistenceKey, this.store.serialize(), {
didCancel: () => this.didDispose
});
await storeSnapshotInIndexedDb(
this.universalPersistenceKey,
this.store.schema,
this.store.serialize(),
{
didCancel: () => this.didDispose
}
);
} else {
const diffs = squashRecordDiffs(diffQueue);
await storeChangesInIndexedDb(this.universalPersistenceKey, diffs);
await storeChangesInIndexedDb(this.universalPersistenceKey, this.store.schema, diffs);
}

@@ -212,0 +232,0 @@ this.didLastWriteError = false;

@@ -7,2 +7,3 @@ import { ReadySyncedStore } from '@tldraw/tldraw-beta';

import { SyncedStore } from '@tldraw/tldraw-beta';
import { TldrawConfig } from '@tldraw/tldraw-beta';
import { TLIncompatibilityReason } from '@tldraw/tlsync';

@@ -12,3 +13,7 @@ import { TLInstanceId } from '@tldraw/tldraw-beta';

import { TLRecord } from '@tldraw/tldraw-beta';
import { TLStore } from '@tldraw/tldraw-beta';
import { TLStoreSchema } from '@tldraw/tldraw-beta';
import { TLStoreSnapshot } from '@tldraw/tlschema';
import { TLUser } from '@tldraw/tldraw-beta';
import { TLUserId } from '@tldraw/tldraw-beta';

@@ -47,3 +52,3 @@ /** @public */

/** @public */
export declare function loadDataFromStore(universalPersistenceKey: string, opts?: {
export declare function loadDataFromStore(universalPersistenceKey: string, schema: TLStoreSchema, opts?: {
didCancel?: () => boolean;

@@ -78,12 +83,6 @@ }): Promise<undefined | {

/** @public */
export declare function showCantReadFromIndexDbAlert(): void;
/** @public */
export declare function showCantWriteToIndexDbAlert(): void;
/** @public */
export declare const STORE_PREFIX = "TLDRAW_DOCUMENT_v2";
/** @public */
export declare function storeChangesInIndexedDb(universalPersistenceKey: string, changes: RecordsDiff<any>, opts?: {
export declare function storeChangesInIndexedDb(universalPersistenceKey: string, schema: TLStoreSchema, changes: RecordsDiff<any>, opts?: {
didCancel?: () => boolean;

@@ -93,3 +92,3 @@ }): Promise<void>;

/** @public */
export declare function storeSnapshotInIndexedDb(universalPersistenceKey: string, snapshot: StoreSnapshot<any>, opts?: {
export declare function storeSnapshotInIndexedDb(universalPersistenceKey: string, schema: TLStoreSchema, snapshot: StoreSnapshot<any>, opts?: {
didCancel?: () => boolean;

@@ -118,3 +117,3 @@ }): Promise<void>;

export declare class TLLocalSyncClient {
readonly store: Store<TLRecord>;
readonly store: TLStore;
readonly channel: BroadcastChannelMock | BroadcastChannel;

@@ -127,2 +126,3 @@ private disposables;

readonly instanceId: TLInstanceId;
readonly userId: TLUserId;
readonly universalPersistenceKey: string;

@@ -133,4 +133,5 @@ readonly serializedSchema: SerializedSchema;

private debug;
constructor(store: Store<TLRecord>, { instanceId, universalPersistenceKey, onLoad, onLoadError, }: {
constructor(store: TLStore, { instanceId, userId, universalPersistenceKey, onLoad, onLoadError, }: {
instanceId: TLInstanceId;
userId: TLUserId;
universalPersistenceKey: string;

@@ -158,9 +159,14 @@ onLoad: (self: TLLocalSyncClient) => void;

*/
export declare function useLocalSyncClient({ universalPersistenceKey, instanceId, }: {
export declare function useLocalSyncClient({ universalPersistenceKey, instanceId, userId, config, initialDataRef, }: {
universalPersistenceKey: string;
instanceId: TLInstanceId;
userId: TLUserId;
config?: TldrawConfig;
initialDataRef?: {
current: StoreSnapshot<TLRecord> | null;
};
}): SyncedStore;
/** @public */
export declare function useRemoteSyncClient({ uri, roomId, instanceId, }: UseSyncClientConfig): RemoteSyncedStore;
export declare function useRemoteSyncClient({ uri, roomId, instanceId, config, snapshotForNewRoomRef, }: UseSyncClientConfig): RemoteSyncedStore;

@@ -172,4 +178,8 @@ /** @public */

instanceId: TLInstanceId_2;
config?: TldrawConfig;
snapshotForNewRoomRef?: {
current: null | TLStoreSnapshot;
};
};
export { }

@@ -5,3 +5,3 @@ {

"description": "A tiny little drawing app (multiplayer sync).",
"version": "0.1.0-alpha.6",
"version": "0.1.0-alpha.7",
"author": "tldraw GB Ltd.",

@@ -53,8 +53,8 @@ "homepage": "https://tldraw.dev",

"dependencies": {
"@tldraw/tldraw-beta": "0.1.0-alpha.6",
"@tldraw/tlstore": "0.1.0-alpha.6",
"@tldraw/tlsync": "0.1.0-alpha.6",
"@tldraw/tldraw-beta": "0.1.0-alpha.7",
"@tldraw/tlstore": "0.1.0-alpha.7",
"@tldraw/tlsync": "0.1.0-alpha.7",
"idb": "^7.1.0",
"signia": "^0.0.7",
"signia-react": "^0.0.7"
"signia": "^0.0.8",
"signia-react": "^0.0.8"
},

@@ -61,0 +61,0 @@ "module": "dist/esm/index.js",

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