publish bemo canaries (#4175)
Switch on package publishing for sync libraries so we can start building templates on the canaries. ### Change type - [x] `other`
This commit is contained in:
parent
c5b2569bfc
commit
348ff9f66a
20 changed files with 631 additions and 30 deletions
1
.github/workflows/publish-canary.yml
vendored
1
.github/workflows/publish-canary.yml
vendored
|
@ -27,3 +27,4 @@ jobs:
|
||||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||||
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
||||||
|
TLDRAW_BEMO_URL: https://canary-demo.tldraw.xyz
|
||||||
|
|
1
.github/workflows/publish-manual.yml
vendored
1
.github/workflows/publish-manual.yml
vendored
|
@ -34,6 +34,7 @@ jobs:
|
||||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||||
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
||||||
|
TLDRAW_BEMO_URL: https://demo.tldraw.xyz
|
||||||
|
|
||||||
publish_templates:
|
publish_templates:
|
||||||
name: Publishes code templates to separate repositories
|
name: Publishes code templates to separate repositories
|
||||||
|
|
1
.github/workflows/publish-new.yml
vendored
1
.github/workflows/publish-new.yml
vendored
|
@ -71,6 +71,7 @@ jobs:
|
||||||
HUPPY_TOKEN: ${{ secrets.HUPPY_TOKEN }}
|
HUPPY_TOKEN: ${{ secrets.HUPPY_TOKEN }}
|
||||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||||
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
||||||
|
TLDRAW_BEMO_URL: https://demo.tldraw.xyz
|
||||||
|
|
||||||
publish_templates:
|
publish_templates:
|
||||||
name: Publishes code templates to separate repositories
|
name: Publishes code templates to separate repositories
|
||||||
|
|
1
.github/workflows/publish-patch.yml
vendored
1
.github/workflows/publish-patch.yml
vendored
|
@ -52,6 +52,7 @@ jobs:
|
||||||
HUPPY_TOKEN: ${{ secrets.HUPPY_TOKEN }}
|
HUPPY_TOKEN: ${{ secrets.HUPPY_TOKEN }}
|
||||||
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||||
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }}
|
||||||
|
TLDRAW_BEMO_URL: https://demo.tldraw.xyz
|
||||||
|
|
||||||
publish_templates:
|
publish_templates:
|
||||||
name: Publishes code templates to separate repositories
|
name: Publishes code templates to separate repositories
|
||||||
|
|
503
packages/sync-core/api-report.md
Normal file
503
packages/sync-core/api-report.md
Normal file
|
@ -0,0 +1,503 @@
|
||||||
|
## API Report File for "@tldraw/sync-core"
|
||||||
|
|
||||||
|
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||||
|
|
||||||
|
```ts
|
||||||
|
|
||||||
|
import { Atom } from '@tldraw/state';
|
||||||
|
import { Emitter } from 'nanoevents';
|
||||||
|
import { RecordsDiff } from '@tldraw/store';
|
||||||
|
import { RecordType } from '@tldraw/store';
|
||||||
|
import { Result } from '@tldraw/utils';
|
||||||
|
import { SerializedSchema } from '@tldraw/store';
|
||||||
|
import { Signal } from '@tldraw/state';
|
||||||
|
import { Store } from '@tldraw/store';
|
||||||
|
import { StoreSchema } from '@tldraw/store';
|
||||||
|
import { TLRecord } from '@tldraw/tlschema';
|
||||||
|
import { UnknownRecord } from '@tldraw/store';
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type AppendOp = [type: typeof ValueOpType.Append, values: unknown[], offset: number];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export function applyObjectDiff<T extends object>(object: T, objectDiff: ObjectDiff): T;
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export function chunk(msg: string, maxSafeMessageSize?: number): string[];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export class ClientWebSocketAdapter implements TLPersistentClientSocket<TLRecord> {
|
||||||
|
constructor(getUri: () => Promise<string> | string);
|
||||||
|
// (undocumented)
|
||||||
|
close(): void;
|
||||||
|
// (undocumented)
|
||||||
|
_closeSocket(): void;
|
||||||
|
// (undocumented)
|
||||||
|
get connectionStatus(): TLPersistentClientSocketStatus;
|
||||||
|
// (undocumented)
|
||||||
|
_connectionStatus: Atom<'initial' | TLPersistentClientSocketStatus>;
|
||||||
|
// (undocumented)
|
||||||
|
isDisposed: boolean;
|
||||||
|
// (undocumented)
|
||||||
|
onReceiveMessage(cb: (val: TLSocketServerSentEvent<TLRecord>) => void): () => void;
|
||||||
|
// (undocumented)
|
||||||
|
onStatusChange(cb: (val: TLPersistentClientSocketStatus, closeCode?: number) => void): () => void;
|
||||||
|
// @internal (undocumented)
|
||||||
|
readonly _reconnectManager: ReconnectManager;
|
||||||
|
// (undocumented)
|
||||||
|
restart(): void;
|
||||||
|
// (undocumented)
|
||||||
|
sendMessage(msg: TLSocketClientSentEvent<TLRecord>): void;
|
||||||
|
// (undocumented)
|
||||||
|
_setNewSocket(ws: WebSocket): void;
|
||||||
|
// (undocumented)
|
||||||
|
_ws: null | WebSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type DeleteOp = [type: typeof ValueOpType.Delete];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export function diffRecord(prev: object, next: object): null | ObjectDiff;
|
||||||
|
|
||||||
|
// @internal (undocumented)
|
||||||
|
export class DocumentState<R extends UnknownRecord> {
|
||||||
|
// (undocumented)
|
||||||
|
_atom: Atom<{
|
||||||
|
lastChangedClock: number;
|
||||||
|
state: R;
|
||||||
|
}>;
|
||||||
|
// (undocumented)
|
||||||
|
static createAndValidate<R extends UnknownRecord>(state: R, lastChangedClock: number, recordType: RecordType<R, any>): Result<DocumentState<R>, Error>;
|
||||||
|
// (undocumented)
|
||||||
|
static createWithoutValidating<R extends UnknownRecord>(state: R, lastChangedClock: number, recordType: RecordType<R, any>): DocumentState<R>;
|
||||||
|
// (undocumented)
|
||||||
|
get lastChangedClock(): number;
|
||||||
|
// (undocumented)
|
||||||
|
mergeDiff(diff: ObjectDiff, clock: number): Result<null | ObjectDiff, Error>;
|
||||||
|
// (undocumented)
|
||||||
|
replaceState(state: R, clock: number): Result<null | ObjectDiff, Error>;
|
||||||
|
// (undocumented)
|
||||||
|
get state(): R;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public
|
||||||
|
export const getNetworkDiff: <R extends UnknownRecord>(diff: RecordsDiff<R>) => NetworkDiff<R> | null;
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export function getTlsyncProtocolVersion(): number;
|
||||||
|
|
||||||
|
// @public
|
||||||
|
export interface NetworkDiff<R extends UnknownRecord> {
|
||||||
|
// (undocumented)
|
||||||
|
[id: string]: RecordOp<R>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface ObjectDiff {
|
||||||
|
// (undocumented)
|
||||||
|
[k: string]: ValueOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type PatchOp = [type: typeof ValueOpType.Patch, diff: ObjectDiff];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface PersistedRoomSnapshotForSupabase {
|
||||||
|
// (undocumented)
|
||||||
|
drawing: RoomSnapshot;
|
||||||
|
// (undocumented)
|
||||||
|
id: string;
|
||||||
|
// (undocumented)
|
||||||
|
slug: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type PutOp = [type: typeof ValueOpType.Put, value: unknown];
|
||||||
|
|
||||||
|
// @internal (undocumented)
|
||||||
|
export class ReconnectManager {
|
||||||
|
constructor(socketAdapter: ClientWebSocketAdapter, getUri: () => Promise<string> | string);
|
||||||
|
// (undocumented)
|
||||||
|
close(): void;
|
||||||
|
// (undocumented)
|
||||||
|
connected(): void;
|
||||||
|
// (undocumented)
|
||||||
|
disconnected(): void;
|
||||||
|
// (undocumented)
|
||||||
|
intendedDelay: number;
|
||||||
|
// (undocumented)
|
||||||
|
maybeReconnected(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type RecordOp<R extends UnknownRecord> = [typeof RecordOpType.Patch, ObjectDiff] | [typeof RecordOpType.Put, R] | [typeof RecordOpType.Remove];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export const RecordOpType: {
|
||||||
|
readonly Patch: "patch";
|
||||||
|
readonly Put: "put";
|
||||||
|
readonly Remove: "remove";
|
||||||
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type RecordOpType = (typeof RecordOpType)[keyof typeof RecordOpType];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type RoomSession<R extends UnknownRecord, Meta> = {
|
||||||
|
cancellationTime: number;
|
||||||
|
meta: Meta;
|
||||||
|
presenceId: string;
|
||||||
|
sessionKey: string;
|
||||||
|
socket: TLRoomSocket<R>;
|
||||||
|
state: typeof RoomSessionState.AwaitingRemoval;
|
||||||
|
} | {
|
||||||
|
debounceTimer: null | ReturnType<typeof setTimeout>;
|
||||||
|
lastInteractionTime: number;
|
||||||
|
meta: Meta;
|
||||||
|
outstandingDataMessages: TLSocketServerSentDataEvent<R>[];
|
||||||
|
presenceId: string;
|
||||||
|
serializedSchema: SerializedSchema;
|
||||||
|
sessionKey: string;
|
||||||
|
socket: TLRoomSocket<R>;
|
||||||
|
state: typeof RoomSessionState.Connected;
|
||||||
|
} | {
|
||||||
|
meta: Meta;
|
||||||
|
presenceId: string;
|
||||||
|
sessionKey: string;
|
||||||
|
sessionStartTime: number;
|
||||||
|
socket: TLRoomSocket<R>;
|
||||||
|
state: typeof RoomSessionState.AwaitingConnectMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export const RoomSessionState: {
|
||||||
|
readonly AwaitingConnectMessage: "awaiting-connect-message";
|
||||||
|
readonly AwaitingRemoval: "awaiting-removal";
|
||||||
|
readonly Connected: "connected";
|
||||||
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type RoomSessionState = (typeof RoomSessionState)[keyof typeof RoomSessionState];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface RoomSnapshot {
|
||||||
|
// (undocumented)
|
||||||
|
clock: number;
|
||||||
|
// (undocumented)
|
||||||
|
documents: Array<{
|
||||||
|
lastChangedClock: number;
|
||||||
|
state: UnknownRecord;
|
||||||
|
}>;
|
||||||
|
// (undocumented)
|
||||||
|
schema?: SerializedSchema;
|
||||||
|
// (undocumented)
|
||||||
|
tombstones?: Record<string, number>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type SubscribingFn<T> = (cb: (val: T) => void) => () => void;
|
||||||
|
|
||||||
|
// @public
|
||||||
|
export const TLCloseEventCode: {
|
||||||
|
readonly NOT_FOUND: 4099;
|
||||||
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface TLConnectRequest {
|
||||||
|
// (undocumented)
|
||||||
|
connectRequestId: string;
|
||||||
|
// (undocumented)
|
||||||
|
lastServerClock: number;
|
||||||
|
// (undocumented)
|
||||||
|
protocolVersion: number;
|
||||||
|
// (undocumented)
|
||||||
|
schema: SerializedSchema;
|
||||||
|
// (undocumented)
|
||||||
|
type: 'connect';
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export const TLIncompatibilityReason: {
|
||||||
|
readonly ClientTooOld: "clientTooOld";
|
||||||
|
readonly InvalidOperation: "invalidOperation";
|
||||||
|
readonly InvalidRecord: "invalidRecord";
|
||||||
|
readonly RoomNotFound: "roomNotFound";
|
||||||
|
readonly ServerTooOld: "serverTooOld";
|
||||||
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type TLIncompatibilityReason = (typeof TLIncompatibilityReason)[keyof typeof TLIncompatibilityReason];
|
||||||
|
|
||||||
|
// @public
|
||||||
|
export interface TLPersistentClientSocket<R extends UnknownRecord = UnknownRecord> {
|
||||||
|
connectionStatus: 'error' | 'offline' | 'online';
|
||||||
|
onReceiveMessage: SubscribingFn<TLSocketServerSentEvent<R>>;
|
||||||
|
onStatusChange: SubscribingFn<TLPersistentClientSocketStatus>;
|
||||||
|
restart: () => void;
|
||||||
|
sendMessage: (msg: TLSocketClientSentEvent<R>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type TLPersistentClientSocketStatus = 'error' | 'offline' | 'online';
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface TLPingRequest {
|
||||||
|
// (undocumented)
|
||||||
|
type: 'ping';
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface TLPushRequest<R extends UnknownRecord> {
|
||||||
|
// (undocumented)
|
||||||
|
clientClock: number;
|
||||||
|
// (undocumented)
|
||||||
|
diff?: NetworkDiff<R>;
|
||||||
|
// (undocumented)
|
||||||
|
presence?: [typeof RecordOpType.Patch, ObjectDiff] | [typeof RecordOpType.Put, R];
|
||||||
|
// (undocumented)
|
||||||
|
type: 'push';
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export class TLRemoteSyncError extends Error {
|
||||||
|
constructor(reason: TLIncompatibilityReason);
|
||||||
|
// (undocumented)
|
||||||
|
name: string;
|
||||||
|
// (undocumented)
|
||||||
|
readonly reason: TLIncompatibilityReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface TLRoomSocket<R extends UnknownRecord> {
|
||||||
|
// (undocumented)
|
||||||
|
close: () => void;
|
||||||
|
// (undocumented)
|
||||||
|
isOpen: boolean;
|
||||||
|
// (undocumented)
|
||||||
|
sendMessage: (msg: TLSocketServerSentEvent<R>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type TLSocketClientSentEvent<R extends UnknownRecord> = TLConnectRequest | TLPingRequest | TLPushRequest<R>;
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export class TLSocketRoom<R extends UnknownRecord, SessionMeta> {
|
||||||
|
constructor(opts: {
|
||||||
|
clientTimeout?: number;
|
||||||
|
initialSnapshot?: RoomSnapshot;
|
||||||
|
log?: TLSyncLog;
|
||||||
|
onAfterReceiveMessage?: (args: {
|
||||||
|
message: TLSocketServerSentEvent<R>;
|
||||||
|
meta: SessionMeta;
|
||||||
|
sessionId: string;
|
||||||
|
stringified: string;
|
||||||
|
}) => void;
|
||||||
|
onBeforeSendMessage?: (args: {
|
||||||
|
message: TLSocketServerSentEvent<R>;
|
||||||
|
meta: SessionMeta;
|
||||||
|
sessionId: string;
|
||||||
|
stringified: string;
|
||||||
|
}) => void;
|
||||||
|
onDataChange?: () => void;
|
||||||
|
onSessionRemoved?: (room: TLSocketRoom<R, SessionMeta>, args: {
|
||||||
|
meta: SessionMeta;
|
||||||
|
numSessionsRemaining: number;
|
||||||
|
sessionKey: string;
|
||||||
|
}) => void;
|
||||||
|
schema?: StoreSchema<R, any>;
|
||||||
|
});
|
||||||
|
// (undocumented)
|
||||||
|
close(): void;
|
||||||
|
// (undocumented)
|
||||||
|
getCurrentDocumentClock(): number;
|
||||||
|
// (undocumented)
|
||||||
|
getCurrentSnapshot(): RoomSnapshot;
|
||||||
|
// (undocumented)
|
||||||
|
getNumActiveSessions(): number;
|
||||||
|
// (undocumented)
|
||||||
|
handleSocketClose(sessionId: string): void;
|
||||||
|
// (undocumented)
|
||||||
|
handleSocketConnect(sessionId: string, socket: WebSocket, meta: SessionMeta): void;
|
||||||
|
// (undocumented)
|
||||||
|
handleSocketError(sessionId: string): void;
|
||||||
|
// (undocumented)
|
||||||
|
handleSocketMessage(sessionId: string, message: ArrayBuffer | string): void;
|
||||||
|
// (undocumented)
|
||||||
|
loadSnapshot(snapshot: RoomSnapshot): void;
|
||||||
|
// (undocumented)
|
||||||
|
readonly log: TLSyncLog;
|
||||||
|
// (undocumented)
|
||||||
|
readonly opts: {
|
||||||
|
clientTimeout?: number;
|
||||||
|
initialSnapshot?: RoomSnapshot;
|
||||||
|
log?: TLSyncLog;
|
||||||
|
onAfterReceiveMessage?: (args: {
|
||||||
|
message: TLSocketServerSentEvent<R>;
|
||||||
|
meta: SessionMeta;
|
||||||
|
sessionId: string;
|
||||||
|
stringified: string;
|
||||||
|
}) => void;
|
||||||
|
onBeforeSendMessage?: (args: {
|
||||||
|
message: TLSocketServerSentEvent<R>;
|
||||||
|
meta: SessionMeta;
|
||||||
|
sessionId: string;
|
||||||
|
stringified: string;
|
||||||
|
}) => void;
|
||||||
|
onDataChange?: () => void;
|
||||||
|
onSessionRemoved?: (room: TLSocketRoom<R, SessionMeta>, args: {
|
||||||
|
meta: SessionMeta;
|
||||||
|
numSessionsRemaining: number;
|
||||||
|
sessionKey: string;
|
||||||
|
}) => void;
|
||||||
|
schema?: StoreSchema<R, any>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type TLSocketServerSentDataEvent<R extends UnknownRecord> = {
|
||||||
|
action: 'commit' | 'discard' | {
|
||||||
|
rebaseWithDiff: NetworkDiff<R>;
|
||||||
|
};
|
||||||
|
clientClock: number;
|
||||||
|
serverClock: number;
|
||||||
|
type: 'push_result';
|
||||||
|
} | {
|
||||||
|
diff: NetworkDiff<R>;
|
||||||
|
serverClock: number;
|
||||||
|
type: 'patch';
|
||||||
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type TLSocketServerSentEvent<R extends UnknownRecord> = {
|
||||||
|
connectRequestId: string;
|
||||||
|
diff: NetworkDiff<R>;
|
||||||
|
hydrationType: 'wipe_all' | 'wipe_presence';
|
||||||
|
protocolVersion: number;
|
||||||
|
schema: SerializedSchema;
|
||||||
|
serverClock: number;
|
||||||
|
type: 'connect';
|
||||||
|
} | {
|
||||||
|
data: TLSocketServerSentDataEvent<R>[];
|
||||||
|
type: 'data';
|
||||||
|
} | {
|
||||||
|
error?: any;
|
||||||
|
type: 'error';
|
||||||
|
} | {
|
||||||
|
reason: TLIncompatibilityReason;
|
||||||
|
type: 'incompatibility_error';
|
||||||
|
} | {
|
||||||
|
type: 'pong';
|
||||||
|
} | TLSocketServerSentDataEvent<R>;
|
||||||
|
|
||||||
|
// @public
|
||||||
|
export class TLSyncClient<R extends UnknownRecord, S extends Store<R> = Store<R>> {
|
||||||
|
constructor(config: {
|
||||||
|
didCancel?: () => boolean;
|
||||||
|
onAfterConnect?: (self: TLSyncClient<R, S>, isNew: boolean) => void;
|
||||||
|
onLoad: (self: TLSyncClient<R, S>) => void;
|
||||||
|
onLoadError: (error: Error) => void;
|
||||||
|
onSyncError: (reason: TLIncompatibilityReason) => void;
|
||||||
|
presence: Signal<null | R>;
|
||||||
|
socket: TLPersistentClientSocket<R>;
|
||||||
|
store: S;
|
||||||
|
});
|
||||||
|
// (undocumented)
|
||||||
|
close(): void;
|
||||||
|
// (undocumented)
|
||||||
|
didCancel?: () => boolean;
|
||||||
|
// (undocumented)
|
||||||
|
incomingDiffBuffer: TLSocketServerSentDataEvent<R>[];
|
||||||
|
// (undocumented)
|
||||||
|
isConnectedToRoom: boolean;
|
||||||
|
// (undocumented)
|
||||||
|
lastPushedPresenceState: null | R;
|
||||||
|
// (undocumented)
|
||||||
|
latestConnectRequestId: null | string;
|
||||||
|
readonly onAfterConnect?: (self: TLSyncClient<R, S>, isNew: boolean) => void;
|
||||||
|
// (undocumented)
|
||||||
|
readonly onSyncError: (reason: TLIncompatibilityReason) => void;
|
||||||
|
// (undocumented)
|
||||||
|
readonly presenceState: Signal<null | R> | undefined;
|
||||||
|
// (undocumented)
|
||||||
|
readonly socket: TLPersistentClientSocket<R>;
|
||||||
|
// (undocumented)
|
||||||
|
readonly store: S;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface TLSyncLog {
|
||||||
|
// (undocumented)
|
||||||
|
error?: (...args: any[]) => void;
|
||||||
|
// (undocumented)
|
||||||
|
info?: (...args: any[]) => void;
|
||||||
|
// (undocumented)
|
||||||
|
warn?: (...args: any[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public
|
||||||
|
export class TLSyncRoom<R extends UnknownRecord, SessionMeta> {
|
||||||
|
constructor(schema: StoreSchema<R, any>, snapshot?: RoomSnapshot);
|
||||||
|
broadcastPatch({ diff, sourceSessionKey: sourceSessionKey, }: {
|
||||||
|
diff: NetworkDiff<R>;
|
||||||
|
sourceSessionKey: string;
|
||||||
|
}): this;
|
||||||
|
// (undocumented)
|
||||||
|
clock: number;
|
||||||
|
// (undocumented)
|
||||||
|
close(): void;
|
||||||
|
// (undocumented)
|
||||||
|
documentClock: number;
|
||||||
|
// (undocumented)
|
||||||
|
readonly documentTypes: Set<string>;
|
||||||
|
// (undocumented)
|
||||||
|
readonly events: Emitter< {
|
||||||
|
room_became_empty: () => void;
|
||||||
|
session_removed: (args: {
|
||||||
|
meta: SessionMeta;
|
||||||
|
sessionKey: string;
|
||||||
|
}) => void;
|
||||||
|
}>;
|
||||||
|
// (undocumented)
|
||||||
|
_flushDataMessages(sessionKey: string): void;
|
||||||
|
// (undocumented)
|
||||||
|
getSnapshot(): RoomSnapshot;
|
||||||
|
handleClose: (sessionKey: string) => void;
|
||||||
|
handleMessage: (sessionKey: string, message: TLSocketClientSentEvent<R>) => Promise<void>;
|
||||||
|
handleNewSession: (sessionKey: string, socket: TLRoomSocket<R>, meta: SessionMeta) => this;
|
||||||
|
// (undocumented)
|
||||||
|
readonly presenceType: RecordType<R, any>;
|
||||||
|
// (undocumented)
|
||||||
|
pruneSessions: () => void;
|
||||||
|
// (undocumented)
|
||||||
|
readonly schema: StoreSchema<R, any>;
|
||||||
|
// (undocumented)
|
||||||
|
readonly serializedSchema: SerializedSchema;
|
||||||
|
// (undocumented)
|
||||||
|
readonly sessions: Map<string, RoomSession<R, SessionMeta>>;
|
||||||
|
// @internal (undocumented)
|
||||||
|
state: Atom<{
|
||||||
|
documents: Record<string, DocumentState<R>>;
|
||||||
|
tombstones: Record<string, number>;
|
||||||
|
}, unknown>;
|
||||||
|
// (undocumented)
|
||||||
|
tombstoneHistoryStartsAtClock: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type ValueOp = AppendOp | DeleteOp | PatchOp | PutOp;
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export const ValueOpType: {
|
||||||
|
readonly Append: "append";
|
||||||
|
readonly Delete: "delete";
|
||||||
|
readonly Patch: "patch";
|
||||||
|
readonly Put: "put";
|
||||||
|
};
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type ValueOpType = (typeof ValueOpType)[keyof typeof ValueOpType];
|
||||||
|
|
||||||
|
// (No @packageDocumentation comment for this package)
|
||||||
|
|
||||||
|
```
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@tldraw/sync-core",
|
"name": "@tldraw/sync-core",
|
||||||
"description": "A tiny little drawing app (multiplayer sync).",
|
"description": "A tiny little drawing app (multiplayer sync).",
|
||||||
"version": "2.0.0-alpha.11",
|
"version": "2.3.0",
|
||||||
"private": true,
|
|
||||||
"author": {
|
"author": {
|
||||||
"name": "tldraw GB Ltd.",
|
"name": "tldraw GB Ltd.",
|
||||||
"email": "hello@tldraw.com"
|
"email": "hello@tldraw.com"
|
||||||
|
@ -34,7 +33,12 @@
|
||||||
"test-ci": "lazy inherit",
|
"test-ci": "lazy inherit",
|
||||||
"test": "yarn run -T jest",
|
"test": "yarn run -T jest",
|
||||||
"test-coverage": "lazy inherit",
|
"test-coverage": "lazy inherit",
|
||||||
"lint": "yarn run -T tsx ../../scripts/lint.ts"
|
"lint": "yarn run -T tsx ../../scripts/lint.ts",
|
||||||
|
"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"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"tldraw": "workspace:*",
|
"tldraw": "workspace:*",
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
export { ClientWebSocketAdapter } from './lib/ClientWebSocketAdapter'
|
export { ClientWebSocketAdapter, ReconnectManager } from './lib/ClientWebSocketAdapter'
|
||||||
|
export { RoomSessionState, type RoomSession } from './lib/RoomSession'
|
||||||
export { TLRemoteSyncError } from './lib/TLRemoteSyncError'
|
export { TLRemoteSyncError } from './lib/TLRemoteSyncError'
|
||||||
export { TLSocketRoom } from './lib/TLSocketRoom'
|
export { TLSocketRoom, type TLSyncLog } from './lib/TLSocketRoom'
|
||||||
export {
|
export {
|
||||||
TLCloseEventCode,
|
TLCloseEventCode,
|
||||||
TLSyncClient,
|
TLSyncClient,
|
||||||
|
type SubscribingFn,
|
||||||
type TLPersistentClientSocket,
|
type TLPersistentClientSocket,
|
||||||
type TLPersistentClientSocketStatus,
|
type TLPersistentClientSocketStatus,
|
||||||
} from './lib/TLSyncClient'
|
} from './lib/TLSyncClient'
|
||||||
export { TLSyncRoom, type RoomSnapshot, type TLRoomSocket } from './lib/TLSyncRoom'
|
export { DocumentState, TLSyncRoom, type RoomSnapshot, type TLRoomSocket } from './lib/TLSyncRoom'
|
||||||
export { chunk } from './lib/chunk'
|
export { chunk } from './lib/chunk'
|
||||||
export {
|
export {
|
||||||
RecordOpType,
|
RecordOpType,
|
||||||
|
@ -31,6 +33,7 @@ export {
|
||||||
type TLPingRequest,
|
type TLPingRequest,
|
||||||
type TLPushRequest,
|
type TLPushRequest,
|
||||||
type TLSocketClientSentEvent,
|
type TLSocketClientSentEvent,
|
||||||
|
type TLSocketServerSentDataEvent,
|
||||||
type TLSocketServerSentEvent,
|
type TLSocketServerSentEvent,
|
||||||
} from './lib/protocol'
|
} from './lib/protocol'
|
||||||
export type { PersistedRoomSnapshotForSupabase } from './lib/server-types'
|
export type { PersistedRoomSnapshotForSupabase } from './lib/server-types'
|
||||||
|
|
|
@ -40,11 +40,13 @@ function debug(...args: any[]) {
|
||||||
// pings need to be implemented one level up, on the application API side, which for our
|
// pings need to be implemented one level up, on the application API side, which for our
|
||||||
// codebase means whatever code that uses ClientWebSocketAdapter.
|
// codebase means whatever code that uses ClientWebSocketAdapter.
|
||||||
|
|
||||||
|
/** @public */
|
||||||
export class ClientWebSocketAdapter implements TLPersistentClientSocket<TLRecord> {
|
export class ClientWebSocketAdapter implements TLPersistentClientSocket<TLRecord> {
|
||||||
_ws: WebSocket | null = null
|
_ws: WebSocket | null = null
|
||||||
|
|
||||||
isDisposed = false
|
isDisposed = false
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
readonly _reconnectManager: ReconnectManager
|
readonly _reconnectManager: ReconnectManager
|
||||||
|
|
||||||
// TODO: .close should be a project-wide interface with a common contract (.close()d thing
|
// TODO: .close should be a project-wide interface with a common contract (.close()d thing
|
||||||
|
@ -235,7 +237,8 @@ export const DELAY_EXPONENT = 1.5
|
||||||
// not needlessly reconnecting if the connection is just slow to establish
|
// not needlessly reconnecting if the connection is just slow to establish
|
||||||
export const ATTEMPT_TIMEOUT = 1000
|
export const ATTEMPT_TIMEOUT = 1000
|
||||||
|
|
||||||
class ReconnectManager {
|
/** @internal */
|
||||||
|
export class ReconnectManager {
|
||||||
private isDisposed = false
|
private isDisposed = false
|
||||||
private disposables: (() => void)[] = [
|
private disposables: (() => void)[] = [
|
||||||
() => {
|
() => {
|
||||||
|
|
|
@ -2,18 +2,21 @@ import { SerializedSchema, UnknownRecord } from '@tldraw/store'
|
||||||
import { TLRoomSocket } from './TLSyncRoom'
|
import { TLRoomSocket } from './TLSyncRoom'
|
||||||
import { TLSocketServerSentDataEvent } from './protocol'
|
import { TLSocketServerSentDataEvent } from './protocol'
|
||||||
|
|
||||||
|
/** @public */
|
||||||
export const RoomSessionState = {
|
export const RoomSessionState = {
|
||||||
AwaitingConnectMessage: 'awaiting-connect-message',
|
AwaitingConnectMessage: 'awaiting-connect-message',
|
||||||
AwaitingRemoval: 'awaiting-removal',
|
AwaitingRemoval: 'awaiting-removal',
|
||||||
Connected: 'connected',
|
Connected: 'connected',
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
|
/** @public */
|
||||||
export type RoomSessionState = (typeof RoomSessionState)[keyof typeof RoomSessionState]
|
export type RoomSessionState = (typeof RoomSessionState)[keyof typeof RoomSessionState]
|
||||||
|
|
||||||
export const SESSION_START_WAIT_TIME = 10000
|
export const SESSION_START_WAIT_TIME = 10000
|
||||||
export const SESSION_REMOVAL_WAIT_TIME = 10000
|
export const SESSION_REMOVAL_WAIT_TIME = 10000
|
||||||
export const SESSION_IDLE_TIMEOUT = 20000
|
export const SESSION_IDLE_TIMEOUT = 20000
|
||||||
|
|
||||||
|
/** @public */
|
||||||
export type RoomSession<R extends UnknownRecord, Meta> =
|
export type RoomSession<R extends UnknownRecord, Meta> =
|
||||||
| {
|
| {
|
||||||
state: typeof RoomSessionState.AwaitingConnectMessage
|
state: typeof RoomSessionState.AwaitingConnectMessage
|
||||||
|
|
|
@ -6,12 +6,14 @@ import { JsonChunkAssembler } from './chunk'
|
||||||
import { TLSocketServerSentEvent } from './protocol'
|
import { TLSocketServerSentEvent } from './protocol'
|
||||||
|
|
||||||
// TODO: structured logging support
|
// TODO: structured logging support
|
||||||
interface TLSyncLog {
|
/** @public */
|
||||||
|
export interface TLSyncLog {
|
||||||
info?: (...args: any[]) => void
|
info?: (...args: any[]) => void
|
||||||
warn?: (...args: any[]) => void
|
warn?: (...args: any[]) => void
|
||||||
error?: (...args: any[]) => void
|
error?: (...args: any[]) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @public */
|
||||||
export class TLSocketRoom<R extends UnknownRecord, SessionMeta> {
|
export class TLSocketRoom<R extends UnknownRecord, SessionMeta> {
|
||||||
private room: TLSyncRoom<R, SessionMeta>
|
private room: TLSyncRoom<R, SessionMeta>
|
||||||
private readonly sessions = new Map<
|
private readonly sessions = new Map<
|
||||||
|
|
|
@ -21,10 +21,11 @@ import {
|
||||||
getTlsyncProtocolVersion,
|
getTlsyncProtocolVersion,
|
||||||
} from './protocol'
|
} from './protocol'
|
||||||
|
|
||||||
type SubscribingFn<T> = (cb: (val: T) => void) => () => void
|
/** @public */
|
||||||
|
export type SubscribingFn<T> = (cb: (val: T) => void) => () => void
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are our private codes to be sent from server->client.
|
* These are our private codes to be sent from server-\>client.
|
||||||
* They are in the private range of the websocket code range.
|
* They are in the private range of the websocket code range.
|
||||||
* See: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
|
* See: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
|
||||||
*
|
*
|
||||||
|
|
|
@ -63,7 +63,8 @@ export const DATA_MESSAGE_DEBOUNCE_INTERVAL = 1000 / 60
|
||||||
|
|
||||||
const timeSince = (time: number) => Date.now() - time
|
const timeSince = (time: number) => Date.now() - time
|
||||||
|
|
||||||
class DocumentState<R extends UnknownRecord> {
|
/** @internal */
|
||||||
|
export class DocumentState<R extends UnknownRecord> {
|
||||||
_atom: Atom<{ state: R; lastChangedClock: number }>
|
_atom: Atom<{ state: R; lastChangedClock: number }>
|
||||||
|
|
||||||
static createWithoutValidating<R extends UnknownRecord>(
|
static createWithoutValidating<R extends UnknownRecord>(
|
||||||
|
@ -184,6 +185,7 @@ export class TLSyncRoom<R extends UnknownRecord, SessionMeta> {
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// Values associated with each uid (must be serializable).
|
// Values associated with each uid (must be serializable).
|
||||||
|
/** @internal */
|
||||||
state = atom<{
|
state = atom<{
|
||||||
documents: Record<string, DocumentState<R>>
|
documents: Record<string, DocumentState<R>>
|
||||||
tombstones: Record<string, number>
|
tombstones: Record<string, number>
|
||||||
|
|
|
@ -8,6 +8,7 @@ const MAX_BYTES_PER_CHAR = 4
|
||||||
// in the (admittedly impossible) worst case, the max size is 1/4 of a megabyte
|
// in the (admittedly impossible) worst case, the max size is 1/4 of a megabyte
|
||||||
const MAX_SAFE_MESSAGE_SIZE = MAX_CLIENT_SENT_MESSAGE_SIZE_BYTES / MAX_BYTES_PER_CHAR
|
const MAX_SAFE_MESSAGE_SIZE = MAX_CLIENT_SENT_MESSAGE_SIZE_BYTES / MAX_BYTES_PER_CHAR
|
||||||
|
|
||||||
|
/** @public */
|
||||||
export function chunk(msg: string, maxSafeMessageSize = MAX_SAFE_MESSAGE_SIZE) {
|
export function chunk(msg: string, maxSafeMessageSize = MAX_SAFE_MESSAGE_SIZE) {
|
||||||
if (msg.length < maxSafeMessageSize) {
|
if (msg.length < maxSafeMessageSize) {
|
||||||
return [msg]
|
return [msg]
|
||||||
|
|
|
@ -69,6 +69,7 @@ export const ValueOpType = {
|
||||||
Append: 'append',
|
Append: 'append',
|
||||||
Patch: 'patch',
|
Patch: 'patch',
|
||||||
} as const
|
} as const
|
||||||
|
/** @public */
|
||||||
export type ValueOpType = (typeof ValueOpType)[keyof typeof ValueOpType]
|
export type ValueOpType = (typeof ValueOpType)[keyof typeof ValueOpType]
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { SerializedSchema, UnknownRecord } from '@tldraw/store'
|
import { SerializedSchema, UnknownRecord } from '@tldraw/store'
|
||||||
import { NetworkDiff, ObjectDiff, RecordOpType } from './diff'
|
import { NetworkDiff, ObjectDiff, RecordOpType } from './diff'
|
||||||
|
|
||||||
/** @public */
|
|
||||||
const TLSYNC_PROTOCOL_VERSION = 6
|
const TLSYNC_PROTOCOL_VERSION = 6
|
||||||
|
|
||||||
|
/** @public */
|
||||||
export function getTlsyncProtocolVersion() {
|
export function getTlsyncProtocolVersion() {
|
||||||
return TLSYNC_PROTOCOL_VERSION
|
return TLSYNC_PROTOCOL_VERSION
|
||||||
}
|
}
|
||||||
|
|
64
packages/sync/api-report.md
Normal file
64
packages/sync/api-report.md
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
## API Report File for "@tldraw/sync"
|
||||||
|
|
||||||
|
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||||
|
|
||||||
|
```ts
|
||||||
|
|
||||||
|
import { Editor } from 'tldraw';
|
||||||
|
import { Signal } from 'tldraw';
|
||||||
|
import { TLAssetStore } from 'tldraw';
|
||||||
|
import { TLSchema } from 'tldraw';
|
||||||
|
import { TLStoreWithStatus } from 'tldraw';
|
||||||
|
import { TLUserPreferences } from 'tldraw';
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export type RemoteTLStoreWithStatus = Exclude<TLStoreWithStatus, {
|
||||||
|
status: 'not-synced';
|
||||||
|
} | {
|
||||||
|
status: 'synced-local';
|
||||||
|
}>;
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export function useMultiplayerDemo(options: UseMultiplayerDemoOptions): RemoteTLStoreWithStatus;
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface UseMultiplayerDemoOptions {
|
||||||
|
// @internal (undocumented)
|
||||||
|
host?: string;
|
||||||
|
// (undocumented)
|
||||||
|
roomId: string;
|
||||||
|
// (undocumented)
|
||||||
|
schema?: TLSchema;
|
||||||
|
// (undocumented)
|
||||||
|
userPreferences?: Signal<TLUserPreferences>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export function useMultiplayerSync(opts: UseMultiplayerSyncOptions): RemoteTLStoreWithStatus;
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
export interface UseMultiplayerSyncOptions {
|
||||||
|
// (undocumented)
|
||||||
|
assets?: Partial<TLAssetStore>;
|
||||||
|
// (undocumented)
|
||||||
|
onEditorMount?: (editor: Editor) => void;
|
||||||
|
// (undocumented)
|
||||||
|
roomId?: string;
|
||||||
|
// (undocumented)
|
||||||
|
schema?: TLSchema;
|
||||||
|
// (undocumented)
|
||||||
|
trackAnalyticsEvent?(name: string, data: {
|
||||||
|
[key: string]: any;
|
||||||
|
}): void;
|
||||||
|
// (undocumented)
|
||||||
|
uri: string;
|
||||||
|
// (undocumented)
|
||||||
|
userPreferences?: Signal<TLUserPreferences>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export * from "@tldraw/sync-core";
|
||||||
|
|
||||||
|
// (No @packageDocumentation comment for this package)
|
||||||
|
|
||||||
|
```
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@tldraw/sync",
|
"name": "@tldraw/sync",
|
||||||
"description": "A tiny little drawing app (multiplayer sync react bindings).",
|
"description": "A tiny little drawing app (multiplayer sync react bindings).",
|
||||||
"version": "2.0.0-alpha.11",
|
"version": "2.3.0",
|
||||||
"private": true,
|
|
||||||
"author": {
|
"author": {
|
||||||
"name": "tldraw GB Ltd.",
|
"name": "tldraw GB Ltd.",
|
||||||
"email": "hello@tldraw.com"
|
"email": "hello@tldraw.com"
|
||||||
|
@ -34,7 +33,12 @@
|
||||||
"test-ci": "lazy inherit",
|
"test-ci": "lazy inherit",
|
||||||
"test": "yarn run -T jest",
|
"test": "yarn run -T jest",
|
||||||
"test-coverage": "lazy inherit",
|
"test-coverage": "lazy inherit",
|
||||||
"lint": "yarn run -T tsx ../../scripts/lint.ts"
|
"lint": "yarn run -T tsx ../../scripts/lint.ts",
|
||||||
|
"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"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
|
|
|
@ -41,12 +41,9 @@ function getEnv(cb: () => string | undefined): string | undefined {
|
||||||
const DEMO_WORKER = getEnv(() => process.env.TLDRAW_BEMO_URL) ?? 'https://demo.tldraw.xyz'
|
const DEMO_WORKER = getEnv(() => process.env.TLDRAW_BEMO_URL) ?? 'https://demo.tldraw.xyz'
|
||||||
const IMAGE_WORKER = getEnv(() => process.env.TLDRAW_IMAGE_URL) ?? 'https://images.tldraw.xyz'
|
const IMAGE_WORKER = getEnv(() => process.env.TLDRAW_IMAGE_URL) ?? 'https://images.tldraw.xyz'
|
||||||
|
|
||||||
export function useMultiplayerDemo({
|
/** @public */
|
||||||
roomId,
|
export function useMultiplayerDemo(options: UseMultiplayerDemoOptions): RemoteTLStoreWithStatus {
|
||||||
userPreferences,
|
const { roomId, userPreferences, host = DEMO_WORKER, schema } = options
|
||||||
host = DEMO_WORKER,
|
|
||||||
schema,
|
|
||||||
}: UseMultiplayerDemoOptions): RemoteTLStoreWithStatus {
|
|
||||||
const assets = useMemo(() => createDemoAssetStore(host), [host])
|
const assets = useMemo(() => createDemoAssetStore(host), [host])
|
||||||
|
|
||||||
return useMultiplayerSync({
|
return useMultiplayerSync({
|
||||||
|
|
|
@ -11,8 +11,7 @@ const packagesOurTypesCanDependOn = [
|
||||||
'@types/react',
|
'@types/react',
|
||||||
'@types/react-dom',
|
'@types/react-dom',
|
||||||
'eventemitter3',
|
'eventemitter3',
|
||||||
// todo: external types shouldn't depend on this
|
'nanoevents',
|
||||||
'@types/ws',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { build } from 'esbuild'
|
import { BuildOptions, build } from 'esbuild'
|
||||||
import { copyFileSync, existsSync } from 'fs'
|
import { copyFileSync, existsSync } from 'fs'
|
||||||
import glob from 'glob'
|
import glob from 'glob'
|
||||||
import kleur from 'kleur'
|
import kleur from 'kleur'
|
||||||
|
@ -42,6 +42,20 @@ async function buildPackage({ sourcePackageDir }: { sourcePackageDir: string })
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCommonEsbuildOptions() {
|
||||||
|
const define: Record<string, string> = {}
|
||||||
|
if (process.env.TLDRAW_BEMO_URL) {
|
||||||
|
define['process.env.TLDRAW_BEMO_URL'] = JSON.stringify(process.env.TLDRAW_BEMO_URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
bundle: false,
|
||||||
|
platform: 'neutral',
|
||||||
|
sourcemap: true,
|
||||||
|
define,
|
||||||
|
} satisfies BuildOptions
|
||||||
|
}
|
||||||
|
|
||||||
/** This uses esbuild to build the esm version of the package */
|
/** This uses esbuild to build the esm version of the package */
|
||||||
async function buildEsm({
|
async function buildEsm({
|
||||||
sourceFiles,
|
sourceFiles,
|
||||||
|
@ -55,11 +69,9 @@ async function buildEsm({
|
||||||
const res = await build({
|
const res = await build({
|
||||||
entryPoints: sourceFiles,
|
entryPoints: sourceFiles,
|
||||||
outdir,
|
outdir,
|
||||||
bundle: false,
|
|
||||||
platform: 'neutral',
|
|
||||||
sourcemap: true,
|
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
outExtension: { '.js': '.mjs' },
|
outExtension: { '.js': '.mjs' },
|
||||||
|
...getCommonEsbuildOptions(),
|
||||||
})
|
})
|
||||||
|
|
||||||
addJsExtensions(path.join(sourcePackageDir, 'dist-esm'))
|
addJsExtensions(path.join(sourcePackageDir, 'dist-esm'))
|
||||||
|
@ -84,10 +96,8 @@ async function buildCjs({
|
||||||
const res = await build({
|
const res = await build({
|
||||||
entryPoints: sourceFiles,
|
entryPoints: sourceFiles,
|
||||||
outdir,
|
outdir,
|
||||||
bundle: false,
|
|
||||||
platform: 'neutral',
|
|
||||||
sourcemap: true,
|
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
|
...getCommonEsbuildOptions(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (res.errors.length) {
|
if (res.errors.length) {
|
||||||
|
|
Loading…
Reference in a new issue