2023-04-25 11:01:25 +00:00
|
|
|
## API Report File for "@tldraw/tlschema"
|
|
|
|
|
|
|
|
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
2023-06-03 08:59:04 +00:00
|
|
|
import { BaseRecord } from '@tldraw/store';
|
2023-06-16 10:33:47 +00:00
|
|
|
import { Expand } from '@tldraw/utils';
|
2023-06-03 08:59:04 +00:00
|
|
|
import { Migrations } from '@tldraw/store';
|
2023-06-03 20:46:53 +00:00
|
|
|
import { RecordId } from '@tldraw/store';
|
2023-06-03 08:59:04 +00:00
|
|
|
import { RecordType } from '@tldraw/store';
|
2023-06-20 13:31:26 +00:00
|
|
|
import { Signal } from '@tldraw/state';
|
2023-06-03 08:59:04 +00:00
|
|
|
import { Store } from '@tldraw/store';
|
|
|
|
import { StoreSchema } from '@tldraw/store';
|
|
|
|
import { StoreSnapshot } from '@tldraw/store';
|
2023-06-03 08:27:44 +00:00
|
|
|
import { T } from '@tldraw/validate';
|
2023-06-03 08:59:04 +00:00
|
|
|
import { UnknownRecord } from '@tldraw/store';
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const ArrowShapeArrowheadEndStyle: EnumStyleProp<"arrow" | "bar" | "diamond" | "dot" | "inverted" | "none" | "pipe" | "square" | "triangle">;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const ArrowShapeArrowheadStartStyle: EnumStyleProp<"arrow" | "bar" | "diamond" | "dot" | "inverted" | "none" | "pipe" | "square" | "triangle">;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const arrowShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const arrowShapeProps: {
|
|
|
|
labelColor: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
fill: EnumStyleProp<"none" | "pattern" | "semi" | "solid">;
|
|
|
|
dash: EnumStyleProp<"dashed" | "dotted" | "draw" | "solid">;
|
|
|
|
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
arrowheadStart: EnumStyleProp<"arrow" | "bar" | "diamond" | "dot" | "inverted" | "none" | "pipe" | "square" | "triangle">;
|
|
|
|
arrowheadEnd: EnumStyleProp<"arrow" | "bar" | "diamond" | "dot" | "inverted" | "none" | "pipe" | "square" | "triangle">;
|
|
|
|
font: EnumStyleProp<"draw" | "mono" | "sans" | "serif">;
|
|
|
|
start: T.UnionValidator<"type", {
|
|
|
|
binding: T.ObjectValidator<{
|
|
|
|
type: "binding";
|
|
|
|
boundShapeId: TLShapeId;
|
|
|
|
normalizedAnchor: Vec2dModel;
|
|
|
|
isExact: boolean;
|
|
|
|
}>;
|
|
|
|
point: T.ObjectValidator<{
|
|
|
|
type: "point";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
}>;
|
|
|
|
}, never>;
|
|
|
|
end: T.UnionValidator<"type", {
|
|
|
|
binding: T.ObjectValidator<{
|
|
|
|
type: "binding";
|
|
|
|
boundShapeId: TLShapeId;
|
|
|
|
normalizedAnchor: Vec2dModel;
|
|
|
|
isExact: boolean;
|
|
|
|
}>;
|
|
|
|
point: T.ObjectValidator<{
|
|
|
|
type: "point";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
}>;
|
|
|
|
}, never>;
|
|
|
|
bend: T.Validator<number>;
|
|
|
|
text: T.Validator<string>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
|
|
|
export const assetIdValidator: T.Validator<TLAssetId>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @internal (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export const assetMigrations: Migrations;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-26 13:37:59 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const AssetRecordType: RecordType<TLAsset, "props" | "type">;
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const assetValidator: T.Validator<TLAsset>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const bookmarkShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const bookmarkShapeProps: {
|
|
|
|
w: T.Validator<number>;
|
|
|
|
h: T.Validator<number>;
|
|
|
|
assetId: T.Validator<TLAssetId | null>;
|
|
|
|
url: T.Validator<string>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export interface Box2dModel {
|
|
|
|
// (undocumented)
|
|
|
|
h: number;
|
|
|
|
// (undocumented)
|
|
|
|
w: number;
|
|
|
|
// (undocumented)
|
|
|
|
x: number;
|
|
|
|
// (undocumented)
|
|
|
|
y: number;
|
|
|
|
}
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const box2dModelValidator: T.Validator<Box2dModel>;
|
|
|
|
|
2023-05-26 13:37:59 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const CameraRecordType: RecordType<TLCamera, never>;
|
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @public
|
|
|
|
export const canvasUiColorTypeValidator: T.Validator<"accent" | "black" | "laser" | "muted-1" | "selection-fill" | "selection-stroke" | "white">;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export function CLIENT_FIXUP_SCRIPT(persistedStore: StoreSnapshot<TLRecord>): StoreSnapshot<TLRecord>;
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export function createAssetValidator<Type extends string, Props extends object>(type: Type, props: T.Validator<Props>): T.ObjectValidator<{
|
|
|
|
id: TLAssetId;
|
|
|
|
typeName: 'asset';
|
|
|
|
type: Type;
|
|
|
|
props: Props;
|
|
|
|
}>;
|
|
|
|
|
2023-06-14 22:08:07 +00:00
|
|
|
// @public (undocumented)
|
2023-05-25 09:54:29 +00:00
|
|
|
export const createPresenceStateDerivation: ($user: Signal<{
|
|
|
|
id: string;
|
|
|
|
color: string;
|
|
|
|
name: string;
|
2023-06-16 15:59:13 +00:00
|
|
|
}>, instanceId?: TLInstancePresence['id']) => (store: TLStore) => Signal<null | TLInstancePresence>;
|
2023-05-25 09:54:29 +00:00
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export function createShapeId(id?: string): TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-12 14:04:14 +00:00
|
|
|
export function createShapeValidator<Type extends string, Props extends object>(type: Type, props?: {
|
|
|
|
[K in keyof Props]: T.Validatable<Props[K]>;
|
|
|
|
}): T.ObjectValidator<{
|
2023-04-25 11:01:25 +00:00
|
|
|
id: TLShapeId;
|
|
|
|
typeName: "shape";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
type: Type;
|
|
|
|
isLocked: boolean;
|
2023-06-06 16:15:12 +00:00
|
|
|
opacity: number;
|
2023-06-12 14:04:14 +00:00
|
|
|
props: Props | Record<string, unknown>;
|
2023-04-25 11:01:25 +00:00
|
|
|
}>;
|
|
|
|
|
2023-05-24 10:48:31 +00:00
|
|
|
// @public
|
2023-06-12 14:04:14 +00:00
|
|
|
export function createTLSchema({ shapes }: {
|
|
|
|
shapes: Record<string, SchemaShapeInfo>;
|
|
|
|
}): TLSchema;
|
2023-05-24 10:48:31 +00:00
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const DefaultColorStyle: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const DefaultDashStyle: EnumStyleProp<"dashed" | "dotted" | "draw" | "solid">;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const DefaultFillStyle: EnumStyleProp<"none" | "pattern" | "semi" | "solid">;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const DefaultFontStyle: EnumStyleProp<"draw" | "mono" | "sans" | "serif">;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const DefaultHorizontalAlignStyle: EnumStyleProp<"end-legacy" | "end" | "middle-legacy" | "middle" | "start-legacy" | "start">;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const DefaultSizeStyle: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const DefaultVerticalAlignStyle: EnumStyleProp<"end" | "middle" | "start">;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-26 13:37:59 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const DocumentRecordType: RecordType<TLDocument, never>;
|
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const drawShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const drawShapeProps: {
|
|
|
|
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
fill: EnumStyleProp<"none" | "pattern" | "semi" | "solid">;
|
|
|
|
dash: EnumStyleProp<"dashed" | "dotted" | "draw" | "solid">;
|
|
|
|
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
segments: T.ArrayOfValidator<{
|
|
|
|
type: "free" | "straight";
|
|
|
|
points: Vec2dModel[];
|
|
|
|
}>;
|
|
|
|
isComplete: T.Validator<boolean>;
|
|
|
|
isClosed: T.Validator<boolean>;
|
|
|
|
isPen: T.Validator<boolean>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const EMBED_DEFINITIONS: readonly [{
|
|
|
|
readonly type: "tldraw";
|
|
|
|
readonly title: "tldraw";
|
|
|
|
readonly hostnames: readonly ["beta.tldraw.com", "lite.tldraw.com", "www.tldraw.com"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: true;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "codesandbox";
|
|
|
|
readonly title: "CodeSandbox";
|
|
|
|
readonly hostnames: readonly ["codesandbox.io"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "codepen";
|
|
|
|
readonly title: "Codepen";
|
|
|
|
readonly hostnames: readonly ["codepen.io"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 520;
|
|
|
|
readonly height: 400;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "scratch";
|
|
|
|
readonly title: "Scratch";
|
|
|
|
readonly hostnames: readonly ["scratch.mit.edu"];
|
|
|
|
readonly width: 520;
|
|
|
|
readonly height: 400;
|
|
|
|
readonly doesResize: false;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "youtube";
|
|
|
|
readonly title: "YouTube";
|
|
|
|
readonly hostnames: readonly ["*.youtube.com", "youtube.com", "youtu.be"];
|
|
|
|
readonly width: 800;
|
|
|
|
readonly height: 450;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly overridePermissions: {
|
|
|
|
readonly 'allow-presentation': true;
|
|
|
|
};
|
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "figma";
|
|
|
|
readonly title: "Figma";
|
|
|
|
readonly hostnames: readonly ["figma.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: true;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "google_maps";
|
|
|
|
readonly title: "Google Maps";
|
|
|
|
readonly hostnames: readonly ["google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "google_calendar";
|
|
|
|
readonly title: "Google Calendar";
|
|
|
|
readonly hostnames: readonly ["calendar.google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minWidth: 460;
|
|
|
|
readonly minHeight: 360;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly instructionLink: "https://support.google.com/calendar/answer/41207?hl=en";
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "google_slides";
|
|
|
|
readonly title: "Google Slides";
|
|
|
|
readonly hostnames: readonly ["docs.google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minWidth: 460;
|
|
|
|
readonly minHeight: 360;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "github_gist";
|
|
|
|
readonly title: "GitHub Gist";
|
|
|
|
readonly hostnames: readonly ["gist.github.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: true;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "replit";
|
|
|
|
readonly title: "Replit";
|
|
|
|
readonly hostnames: readonly ["replit.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "felt";
|
|
|
|
readonly title: "Felt";
|
|
|
|
readonly hostnames: readonly ["felt.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "spotify";
|
|
|
|
readonly title: "Spotify";
|
|
|
|
readonly hostnames: readonly ["open.spotify.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minHeight: 500;
|
|
|
|
readonly overrideOutlineRadius: 12;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "vimeo";
|
|
|
|
readonly title: "Vimeo";
|
|
|
|
readonly hostnames: readonly ["vimeo.com", "player.vimeo.com"];
|
|
|
|
readonly width: 640;
|
|
|
|
readonly height: 360;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "excalidraw";
|
|
|
|
readonly title: "Excalidraw";
|
|
|
|
readonly hostnames: readonly ["excalidraw.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}, {
|
|
|
|
readonly type: "observable";
|
|
|
|
readonly title: "Observable";
|
|
|
|
readonly hostnames: readonly ["observablehq.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: false;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly isAspectRatioLocked: false;
|
|
|
|
readonly backgroundColor: "#fff";
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
}];
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type EmbedDefinition = {
|
|
|
|
readonly type: string;
|
|
|
|
readonly title: string;
|
|
|
|
readonly hostnames: readonly string[];
|
|
|
|
readonly minWidth?: number;
|
|
|
|
readonly minHeight?: number;
|
|
|
|
readonly width: number;
|
|
|
|
readonly height: number;
|
|
|
|
readonly doesResize: boolean;
|
2023-06-13 08:27:54 +00:00
|
|
|
readonly canUnmount: boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly isAspectRatioLocked?: boolean;
|
|
|
|
readonly overridePermissions?: TLEmbedShapePermissions;
|
|
|
|
readonly instructionLink?: string;
|
|
|
|
readonly backgroundColor?: string;
|
|
|
|
readonly overrideOutlineRadius?: number;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
};
|
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const embedShapeMigrations: Migrations;
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
|
|
|
export const embedShapePermissionDefaults: {
|
|
|
|
readonly 'allow-downloads-without-user-activation': false;
|
|
|
|
readonly 'allow-downloads': false;
|
|
|
|
readonly 'allow-modals': false;
|
|
|
|
readonly 'allow-orientation-lock': false;
|
|
|
|
readonly 'allow-pointer-lock': false;
|
|
|
|
readonly 'allow-popups': true;
|
|
|
|
readonly 'allow-popups-to-escape-sandbox': false;
|
|
|
|
readonly 'allow-presentation': false;
|
|
|
|
readonly 'allow-storage-access-by-user-activation': false;
|
|
|
|
readonly 'allow-top-navigation': false;
|
|
|
|
readonly 'allow-top-navigation-by-user-activation': false;
|
|
|
|
readonly 'allow-scripts': true;
|
|
|
|
readonly 'allow-same-origin': true;
|
|
|
|
readonly 'allow-forms': true;
|
|
|
|
};
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const embedShapeProps: {
|
|
|
|
w: T.Validator<number>;
|
|
|
|
h: T.Validator<number>;
|
|
|
|
url: T.Validator<string>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export class EnumStyleProp<T> extends StyleProp<T> {
|
|
|
|
// @internal
|
|
|
|
constructor(id: string, defaultValue: T, values: readonly T[]);
|
|
|
|
// (undocumented)
|
|
|
|
readonly values: readonly T[];
|
|
|
|
}
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export function fixupRecord(oldRecord: TLRecord): {
|
|
|
|
record: any;
|
|
|
|
issues: string[];
|
|
|
|
};
|
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const frameShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const frameShapeProps: {
|
|
|
|
w: T.Validator<number>;
|
|
|
|
h: T.Validator<number>;
|
|
|
|
name: T.Validator<string>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const GeoShapeGeoStyle: EnumStyleProp<"arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "check-box" | "diamond" | "ellipse" | "hexagon" | "octagon" | "oval" | "pentagon" | "rectangle" | "rhombus-2" | "rhombus" | "star" | "trapezoid" | "triangle" | "x-box">;
|
2023-06-12 14:04:14 +00:00
|
|
|
|
|
|
|
// @internal (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export const geoShapeMigrations: Migrations;
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const geoShapeProps: {
|
|
|
|
geo: EnumStyleProp<"arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "check-box" | "diamond" | "ellipse" | "hexagon" | "octagon" | "oval" | "pentagon" | "rectangle" | "rhombus-2" | "rhombus" | "star" | "trapezoid" | "triangle" | "x-box">;
|
|
|
|
labelColor: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
fill: EnumStyleProp<"none" | "pattern" | "semi" | "solid">;
|
|
|
|
dash: EnumStyleProp<"dashed" | "dotted" | "draw" | "solid">;
|
|
|
|
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
font: EnumStyleProp<"draw" | "mono" | "sans" | "serif">;
|
|
|
|
align: EnumStyleProp<"end-legacy" | "end" | "middle-legacy" | "middle" | "start-legacy" | "start">;
|
|
|
|
verticalAlign: EnumStyleProp<"end" | "middle" | "start">;
|
|
|
|
url: T.Validator<string>;
|
|
|
|
w: T.Validator<number>;
|
|
|
|
h: T.Validator<number>;
|
|
|
|
growY: T.Validator<number>;
|
|
|
|
text: T.Validator<string>;
|
|
|
|
};
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-25 09:54:29 +00:00
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export function getDefaultTranslationLocale(): TLLanguage['locale'];
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export function getShapePropKeysByStyle(props: Record<string, T.Validatable<any>>): Map<StyleProp<unknown>, string>;
|
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const groupShapeMigrations: Migrations;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const groupShapeProps: ShapeProps<TLGroupShape>;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const highlightShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const highlightShapeProps: {
|
|
|
|
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
segments: T.ArrayOfValidator<{
|
|
|
|
type: "free" | "straight";
|
|
|
|
points: Vec2dModel[];
|
|
|
|
}>;
|
|
|
|
isComplete: T.Validator<boolean>;
|
|
|
|
isPen: T.Validator<boolean>;
|
|
|
|
};
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @internal (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export function idValidator<Id extends RecordId<UnknownRecord>>(prefix: Id['__type__']['typeName']): T.Validator<Id>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const imageShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const imageShapeProps: {
|
|
|
|
w: T.Validator<number>;
|
|
|
|
h: T.Validator<number>;
|
|
|
|
playing: T.Validator<boolean>;
|
|
|
|
url: T.Validator<string>;
|
|
|
|
assetId: T.Validator<TLAssetId | null>;
|
|
|
|
crop: T.Validator<{
|
|
|
|
topLeft: Vec2dModel;
|
|
|
|
bottomRight: Vec2dModel;
|
|
|
|
} | null>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-05-26 13:37:59 +00:00
|
|
|
// @public (undocumented)
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
export const InstancePageStateRecordType: RecordType<TLInstancePageState, "pageId">;
|
2023-05-26 13:37:59 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
export const InstancePresenceRecordType: RecordType<TLInstancePresence, "currentPageId" | "userId" | "userName">;
|
2023-05-26 13:37:59 +00:00
|
|
|
|
2023-05-27 17:53:18 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function isPageId(id: string): id is TLPageId;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
2023-05-24 11:25:41 +00:00
|
|
|
export function isShape(record?: UnknownRecord): record is TLShape;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function isShapeId(id?: string): id is TLShapeId;
|
|
|
|
|
2023-05-23 12:32:42 +00:00
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export const LANGUAGES: readonly [{
|
|
|
|
readonly locale: "ar";
|
|
|
|
readonly label: "عربي";
|
|
|
|
}, {
|
|
|
|
readonly locale: "ca";
|
|
|
|
readonly label: "Català";
|
|
|
|
}, {
|
|
|
|
readonly locale: "da";
|
|
|
|
readonly label: "Danish";
|
|
|
|
}, {
|
|
|
|
readonly locale: "de";
|
|
|
|
readonly label: "Deutsch";
|
|
|
|
}, {
|
|
|
|
readonly locale: "en";
|
|
|
|
readonly label: "English";
|
|
|
|
}, {
|
|
|
|
readonly locale: "es";
|
|
|
|
readonly label: "Español";
|
|
|
|
}, {
|
|
|
|
readonly locale: "fa";
|
|
|
|
readonly label: "فارسی";
|
|
|
|
}, {
|
|
|
|
readonly locale: "fi";
|
|
|
|
readonly label: "Suomi";
|
|
|
|
}, {
|
|
|
|
readonly locale: "fr";
|
|
|
|
readonly label: "Français";
|
|
|
|
}, {
|
|
|
|
readonly locale: "gl";
|
|
|
|
readonly label: "Galego";
|
|
|
|
}, {
|
|
|
|
readonly locale: "he";
|
|
|
|
readonly label: "עברית";
|
|
|
|
}, {
|
|
|
|
readonly locale: "it";
|
|
|
|
readonly label: "Italiano";
|
|
|
|
}, {
|
|
|
|
readonly locale: "ja";
|
|
|
|
readonly label: "日本語";
|
|
|
|
}, {
|
|
|
|
readonly locale: "ko-kr";
|
|
|
|
readonly label: "한국어";
|
|
|
|
}, {
|
|
|
|
readonly locale: "ku";
|
|
|
|
readonly label: "کوردی";
|
|
|
|
}, {
|
|
|
|
readonly locale: "hi-in";
|
|
|
|
readonly label: "हिन्दी";
|
|
|
|
}, {
|
|
|
|
readonly locale: "hu";
|
|
|
|
readonly label: "Magyar";
|
|
|
|
}, {
|
|
|
|
readonly locale: "my";
|
|
|
|
readonly label: "မြန်မာစာ";
|
|
|
|
}, {
|
|
|
|
readonly locale: "ne";
|
|
|
|
readonly label: "नेपाली";
|
|
|
|
}, {
|
|
|
|
readonly locale: "no";
|
|
|
|
readonly label: "Norwegian";
|
|
|
|
}, {
|
|
|
|
readonly locale: "pl";
|
|
|
|
readonly label: "Polski";
|
|
|
|
}, {
|
|
|
|
readonly locale: "pt-br";
|
|
|
|
readonly label: "Português - Brasil";
|
|
|
|
}, {
|
|
|
|
readonly locale: "pt-pt";
|
|
|
|
readonly label: "Português - Europeu";
|
|
|
|
}, {
|
|
|
|
readonly locale: "ro";
|
|
|
|
readonly label: "Română";
|
|
|
|
}, {
|
|
|
|
readonly locale: "ru";
|
|
|
|
readonly label: "Russian";
|
|
|
|
}, {
|
|
|
|
readonly locale: "sv";
|
|
|
|
readonly label: "Svenska";
|
|
|
|
}, {
|
|
|
|
readonly locale: "te";
|
|
|
|
readonly label: "తెలుగు";
|
|
|
|
}, {
|
|
|
|
readonly locale: "th";
|
|
|
|
readonly label: "ภาษาไทย";
|
|
|
|
}, {
|
|
|
|
readonly locale: "tr";
|
|
|
|
readonly label: "Türkçe";
|
|
|
|
}, {
|
|
|
|
readonly locale: "uk";
|
|
|
|
readonly label: "Ukrainian";
|
|
|
|
}, {
|
|
|
|
readonly locale: "vi";
|
|
|
|
readonly label: "Tiếng Việt";
|
|
|
|
}, {
|
|
|
|
readonly locale: "zh-cn";
|
|
|
|
readonly label: "Chinese - Simplified";
|
|
|
|
}, {
|
|
|
|
readonly locale: "zh-tw";
|
|
|
|
readonly label: "繁體中文 (台灣)";
|
|
|
|
}];
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const lineShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const lineShapeProps: {
|
|
|
|
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
dash: EnumStyleProp<"dashed" | "dotted" | "draw" | "solid">;
|
|
|
|
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
spline: EnumStyleProp<"cubic" | "line">;
|
|
|
|
handles: T.DictValidator<string, TLHandle>;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const LineShapeSplineStyle: EnumStyleProp<"cubic" | "line">;
|
2023-06-12 14:04:14 +00:00
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const noteShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const noteShapeProps: {
|
|
|
|
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
font: EnumStyleProp<"draw" | "mono" | "sans" | "serif">;
|
|
|
|
align: EnumStyleProp<"end-legacy" | "end" | "middle-legacy" | "middle" | "start-legacy" | "start">;
|
|
|
|
verticalAlign: EnumStyleProp<"end" | "middle" | "start">;
|
|
|
|
growY: T.Validator<number>;
|
|
|
|
url: T.Validator<string>;
|
|
|
|
text: T.Validator<string>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal (undocumented)
|
2023-06-06 16:15:12 +00:00
|
|
|
export const opacityValidator: T.Validator<number>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const pageIdValidator: T.Validator<TLPageId>;
|
|
|
|
|
2023-05-26 13:37:59 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const PageRecordType: RecordType<TLPage, "index" | "name">;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const parentIdValidator: T.Validator<TLParentId>;
|
|
|
|
|
2023-05-26 13:37:59 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const PointerRecordType: RecordType<TLPointer, never>;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export const rootShapeMigrations: Migrations;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export type SchemaShapeInfo = {
|
|
|
|
migrations?: Migrations;
|
|
|
|
props?: Record<string, {
|
|
|
|
validate: (prop: any) => any;
|
|
|
|
}>;
|
|
|
|
};
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const scribbleValidator: T.Validator<TLScribble>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const shapeIdValidator: T.Validator<TLShapeId>;
|
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export type ShapeProps<Shape extends TLBaseShape<any, any>> = {
|
2023-06-16 10:33:47 +00:00
|
|
|
[K in keyof Shape['props']]: T.Validatable<Shape['props'][K]>;
|
2023-06-12 14:04:14 +00:00
|
|
|
};
|
|
|
|
|
2023-06-03 21:32:14 +00:00
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export class StyleProp<Type> implements T.Validatable<Type> {
|
`ShapeUtil` refactor, `Editor` cleanup (#1611)
This PR improves the ergonomics of `ShapeUtil` classes.
### Cached methods
First, I've remove the cached methods (such as `bounds`) from the
`ShapeUtil` class and lifted this to the `Editor` class.
Previously, calling `ShapeUtil.getBounds` would return the un-cached
bounds of a shape, while calling `ShapeUtil.bounds` would return the
cached bounds of a shape. We also had `Editor.getBounds`, which would
call `ShapeUtil.bounds`. It was confusing. The cached methods like
`outline` were also marked with "please don't override", which suggested
the architecture was just wrong.
The only weirdness from this is that utils sometimes reach out to the
editor for cached versions of data rather than calling their own cached
methods. It's still an easier story to tell than what we had before.
### More defaults
We now have three and only three `abstract` methods for a `ShapeUtil`:
- `getDefaultProps` (renamed from `defaultProps`)
- `getBounds`,
- `component`
- `indicator`
Previously, we also had `getCenter` as an abstract method, though this
was usually just the middle of the bounds anyway.
### Editing bounds
This PR removes the concept of editingBounds. The viewport will no
longer animate to editing shapes.
### Active area manager
This PR also removes the active area manager, which was not being used
in the way we expected it to be.
### Dpr manager
This PR removes the dpr manager and uses a hook instead to update it
from React. This is one less runtime browser dependency in the app, one
less thing to document.
### Moving things around
This PR also continues to try to organize related methods and properties
in the editor.
### Change Type
- [x] `major` — Breaking change
### Release Notes
- [editor] renames `defaultProps` to `getDefaultProps`
- [editor] removes `outline`, `outlineSegments`, `handles`, `bounds`
- [editor] renames `renderBackground` to `backgroundComponent`
2023-06-19 14:01:18 +00:00
|
|
|
constructor(id: string, defaultValue: Type, type: T.Validatable<Type>);
|
2023-05-19 10:23:43 +00:00
|
|
|
// (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
readonly defaultValue: Type;
|
2023-05-19 10:23:43 +00:00
|
|
|
// (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
static define<Type>(uniqueId: string, { defaultValue, type }: {
|
|
|
|
defaultValue: Type;
|
|
|
|
type?: T.Validatable<Type>;
|
|
|
|
}): StyleProp<Type>;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
static defineEnum<const Values extends readonly unknown[]>(uniqueId: string, { defaultValue, values }: {
|
|
|
|
defaultValue: Values[number];
|
|
|
|
values: Values;
|
|
|
|
}): EnumStyleProp<Values[number]>;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
readonly id: string;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
readonly type: T.Validatable<Type>;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
validate(value: unknown): Type;
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const textShapeMigrations: Migrations;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export const textShapeProps: {
|
|
|
|
color: EnumStyleProp<"black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow">;
|
|
|
|
size: EnumStyleProp<"l" | "m" | "s" | "xl">;
|
|
|
|
font: EnumStyleProp<"draw" | "mono" | "sans" | "serif">;
|
|
|
|
align: EnumStyleProp<"end-legacy" | "end" | "middle-legacy" | "middle" | "start-legacy" | "start">;
|
|
|
|
w: T.Validator<number>;
|
|
|
|
text: T.Validator<string>;
|
|
|
|
scale: T.Validator<number>;
|
|
|
|
autoSize: T.Validator<boolean>;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export const TL_CANVAS_UI_COLOR_TYPES: Set<"accent" | "black" | "laser" | "muted-1" | "selection-fill" | "selection-stroke" | "white">;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLArrowShape = TLBaseShape<'arrow', TLArrowShapeProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLArrowShapeArrowheadStyle = T.TypeOf<typeof ArrowShapeArrowheadStartStyle>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLArrowShapeProps = ShapePropsType<typeof arrowShapeProps>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLArrowShapeTerminal = T.TypeOf<typeof ArrowShapeTerminal>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLAsset = TLBookmarkAsset | TLImageAsset | TLVideoAsset;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export type TLAssetId = RecordId<TLBaseAsset<any, any>>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLAssetPartial<T extends TLAsset = TLAsset> = T extends T ? {
|
|
|
|
id: TLAssetId;
|
|
|
|
type: T['type'];
|
|
|
|
props?: Partial<T['props']>;
|
|
|
|
} & Partial<Omit<T, 'id' | 'props' | 'type'>> : never;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLAssetShape = Extract<TLShape, {
|
|
|
|
props: {
|
|
|
|
assetId: TLAssetId;
|
|
|
|
};
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-05-24 11:25:41 +00:00
|
|
|
export interface TLBaseAsset<Type extends string, Props> extends BaseRecord<'asset', TLAssetId> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
props: Props;
|
|
|
|
// (undocumented)
|
|
|
|
type: Type;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-05-24 11:25:41 +00:00
|
|
|
export interface TLBaseShape<Type extends string, Props extends object> extends BaseRecord<'shape', TLShapeId> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
index: string;
|
|
|
|
// (undocumented)
|
|
|
|
isLocked: boolean;
|
|
|
|
// (undocumented)
|
2023-06-06 16:15:12 +00:00
|
|
|
opacity: TLOpacityType;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
parentId: TLParentId;
|
|
|
|
// (undocumented)
|
|
|
|
props: Props;
|
|
|
|
// (undocumented)
|
|
|
|
rotation: number;
|
|
|
|
// (undocumented)
|
|
|
|
type: Type;
|
|
|
|
// (undocumented)
|
|
|
|
x: number;
|
|
|
|
// (undocumented)
|
|
|
|
y: number;
|
|
|
|
}
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export type TLBookmarkAsset = TLBaseAsset<'bookmark', {
|
|
|
|
title: string;
|
|
|
|
description: string;
|
|
|
|
image: string;
|
|
|
|
src: null | string;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLBookmarkShape = TLBaseShape<'bookmark', TLBookmarkShapeProps>;
|
|
|
|
|
|
|
|
// @public
|
2023-05-24 11:25:41 +00:00
|
|
|
export interface TLCamera extends BaseRecord<'camera', TLCameraId> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
x: number;
|
|
|
|
// (undocumented)
|
|
|
|
y: number;
|
|
|
|
// (undocumented)
|
|
|
|
z: number;
|
|
|
|
}
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
|
|
|
export type TLCameraId = RecordId<TLCamera>;
|
|
|
|
|
|
|
|
// @public
|
2023-06-12 14:04:14 +00:00
|
|
|
export type TLCanvasUiColor = SetValue<typeof TL_CANVAS_UI_COLOR_TYPES>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export interface TLCursor {
|
|
|
|
// (undocumented)
|
2023-06-12 14:04:14 +00:00
|
|
|
color: TLCanvasUiColor;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
rotation: number;
|
|
|
|
// (undocumented)
|
|
|
|
type: TLCursorType;
|
|
|
|
}
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export type TLCursorType = SetValue<typeof TL_CURSOR_TYPES>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLDefaultColorStyle = T.TypeOf<typeof DefaultColorStyle>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLDefaultDashStyle = T.TypeOf<typeof DefaultDashStyle>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLDefaultFillStyle = T.TypeOf<typeof DefaultFillStyle>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLDefaultFontStyle = T.TypeOf<typeof DefaultFontStyle>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLDefaultHorizontalAlignStyle = T.TypeOf<typeof DefaultHorizontalAlignStyle>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-24 10:48:31 +00:00
|
|
|
// @public
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLDefaultShape = TLArrowShape | TLBookmarkShape | TLDrawShape | TLEmbedShape | TLFrameShape | TLGeoShape | TLGroupShape | TLHighlightShape | TLImageShape | TLLineShape | TLNoteShape | TLTextShape | TLVideoShape;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLDefaultSizeStyle = T.TypeOf<typeof DefaultSizeStyle>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLDefaultVerticalAlignStyle = T.TypeOf<typeof DefaultVerticalAlignStyle>;
|
2023-05-24 10:48:31 +00:00
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public
|
2023-06-03 20:46:53 +00:00
|
|
|
export interface TLDocument extends BaseRecord<'document', RecordId<TLDocument>> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
gridSize: number;
|
2023-06-01 18:46:26 +00:00
|
|
|
// (undocumented)
|
|
|
|
name: string;
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export const TLDOCUMENT_ID: RecordId<TLDocument>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLDrawShape = TLBaseShape<'draw', TLDrawShapeProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLDrawShapeSegment = T.TypeOf<typeof DrawShapeSegment>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLEmbedShape = TLBaseShape<'embed', TLEmbedShapeProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLEmbedShapePermissions = {
|
2023-06-03 20:46:53 +00:00
|
|
|
[K in keyof typeof embedShapePermissionDefaults]?: boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLFrameShape = TLBaseShape<'frame', TLFrameShapeProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLGeoShape = TLBaseShape<'geo', TLGeoShapeProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLGroupShape = TLBaseShape<'group', TLGroupShapeProps>;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export interface TLHandle {
|
|
|
|
// (undocumented)
|
|
|
|
canBind?: boolean;
|
|
|
|
id: string;
|
|
|
|
// (undocumented)
|
|
|
|
index: string;
|
|
|
|
// (undocumented)
|
|
|
|
type: TLHandleType;
|
|
|
|
// (undocumented)
|
|
|
|
x: number;
|
|
|
|
// (undocumented)
|
|
|
|
y: number;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export type TLHandleType = SetValue<typeof TL_HANDLE_TYPES>;
|
|
|
|
|
2023-06-01 12:46:13 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export type TLHighlightShape = TLBaseShape<'highlight', TLHighlightShapeProps>;
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export type TLImageAsset = TLBaseAsset<'image', {
|
|
|
|
w: number;
|
|
|
|
h: number;
|
|
|
|
name: string;
|
|
|
|
isAnimated: boolean;
|
|
|
|
mimeType: null | string;
|
|
|
|
src: null | string;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLImageShape = TLBaseShape<'image', TLImageShapeProps>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLImageShapeCrop = T.TypeOf<typeof ImageShapeCrop>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLImageShapeProps = ShapePropsType<typeof imageShapeProps>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public
|
2023-05-24 11:25:41 +00:00
|
|
|
export interface TLInstance extends BaseRecord<'instance', TLInstanceId> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
brush: Box2dModel | null;
|
|
|
|
// (undocumented)
|
2023-06-15 15:10:08 +00:00
|
|
|
chatMessage: string;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
currentPageId: TLPageId;
|
|
|
|
// (undocumented)
|
|
|
|
cursor: TLCursor;
|
|
|
|
// (undocumented)
|
|
|
|
exportBackground: boolean;
|
|
|
|
// (undocumented)
|
2023-05-25 09:54:29 +00:00
|
|
|
followingUserId: null | string;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
2023-06-15 15:48:47 +00:00
|
|
|
highlightedUserIds: string[];
|
|
|
|
// (undocumented)
|
2023-06-15 15:10:08 +00:00
|
|
|
isChatting: boolean;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
isDebugMode: boolean;
|
|
|
|
// (undocumented)
|
|
|
|
isFocusMode: boolean;
|
|
|
|
// (undocumented)
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
isGridMode: boolean;
|
|
|
|
// (undocumented)
|
|
|
|
isPenMode: boolean;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
isToolLocked: boolean;
|
|
|
|
// (undocumented)
|
2023-06-06 16:15:12 +00:00
|
|
|
opacityForNextShape: TLOpacityType;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
screenBounds: Box2dModel;
|
|
|
|
// (undocumented)
|
|
|
|
scribble: null | TLScribble;
|
|
|
|
// (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
stylesForNextShape: Record<string, unknown>;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
zoomBrush: Box2dModel | null;
|
|
|
|
}
|
|
|
|
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const TLINSTANCE_ID: TLInstanceId;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export type TLInstanceId = RecordId<TLInstance>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public
|
2023-05-24 11:25:41 +00:00
|
|
|
export interface TLInstancePageState extends BaseRecord<'instance_page_state', TLInstancePageStateId> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
croppingId: null | TLShapeId;
|
|
|
|
// (undocumented)
|
|
|
|
editingId: null | TLShapeId;
|
|
|
|
// (undocumented)
|
|
|
|
erasingIds: TLShapeId[];
|
|
|
|
// (undocumented)
|
|
|
|
focusLayerId: null | TLShapeId;
|
|
|
|
// (undocumented)
|
|
|
|
hintingIds: TLShapeId[];
|
|
|
|
// (undocumented)
|
|
|
|
hoveredId: null | TLShapeId;
|
|
|
|
// (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
pageId: RecordId<TLPage>;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
selectedIds: TLShapeId[];
|
|
|
|
}
|
|
|
|
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
// @public (undocumented)
|
2023-05-24 11:25:41 +00:00
|
|
|
export interface TLInstancePresence extends BaseRecord<'instance_presence', TLInstancePresenceID> {
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
// (undocumented)
|
|
|
|
brush: Box2dModel | null;
|
|
|
|
// (undocumented)
|
|
|
|
camera: {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
z: number;
|
|
|
|
};
|
|
|
|
// (undocumented)
|
2023-06-15 15:10:08 +00:00
|
|
|
chatMessage: string;
|
|
|
|
// (undocumented)
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
color: string;
|
|
|
|
// (undocumented)
|
|
|
|
currentPageId: TLPageId;
|
|
|
|
// (undocumented)
|
|
|
|
cursor: {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
type: TLCursor['type'];
|
|
|
|
rotation: number;
|
|
|
|
};
|
|
|
|
// (undocumented)
|
2023-05-25 09:54:29 +00:00
|
|
|
followingUserId: null | string;
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
// (undocumented)
|
|
|
|
lastActivityTimestamp: number;
|
|
|
|
// (undocumented)
|
|
|
|
screenBounds: Box2dModel;
|
|
|
|
// (undocumented)
|
|
|
|
scribble: null | TLScribble;
|
|
|
|
// (undocumented)
|
|
|
|
selectedIds: TLShapeId[];
|
|
|
|
// (undocumented)
|
2023-05-25 09:54:29 +00:00
|
|
|
userId: string;
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
// (undocumented)
|
|
|
|
userName: string;
|
|
|
|
}
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export type TLLanguage = (typeof LANGUAGES)[number];
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export type TLLineShape = TLBaseShape<'line', TLLineShapeProps>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLNoteShape = TLBaseShape<'note', TLNoteShapeProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-06 16:15:12 +00:00
|
|
|
export type TLOpacityType = number;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public
|
2023-05-24 11:25:41 +00:00
|
|
|
export interface TLPage extends BaseRecord<'page', TLPageId> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
index: string;
|
|
|
|
// (undocumented)
|
|
|
|
name: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export type TLPageId = RecordId<TLPage>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLParentId = TLPageId | TLShapeId;
|
|
|
|
|
2023-05-25 09:54:29 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const TLPOINTER_ID: TLPointerId;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
Independent instance state persistence (#1493)
This PR
- Removes UserDocumentRecordType
- moving isSnapMode to user preferences
- moving isGridMode and isPenMode to InstanceRecordType
- deleting the other properties which are no longer needed.
- Creates a separate pipeline for persisting instance state.
Previously the instance state records were stored alongside the document
state records, and in order to load the state for a particular instance
(in our case, a particular tab) you needed to pass the 'instanceId'
prop. This prop ended up totally pervading the public API and people ran
into all kinds of issues with it, e.g. using the same instance id in
multiple editor instances.
There was also an issue whereby it was hard for us to clean up old
instance state so the idb table ended up bloating over time.
This PR makes it so that rather than passing an instanceId, you load the
instance state yourself while creating the store. It provides tools to
make that easy.
- Undoes the assumption that we might have more than one instance's
state in the store.
- Like `document`, `instance` now has a singleton id
`instance:instance`.
- Page state ids and camera ids are no longer random, but rather derive
from the page they belong to. This is like having a foreign primary key
in SQL databases. It's something i'd love to support fully as part of
the RecordType/Store api.
Tests to do
- [x] Test Migrations
- [x] Test Store.listen filtering
- [x] Make type sets in Store public and readonly
- [x] Test RecordType.createId
- [x] Test Instance state snapshot loading/exporting
- [x] Manual test File I/O
- [x] Manual test Vscode extension with multiple tabs
- [x] Audit usages of store.query
- [x] Audit usages of changed types: InstanceRecordType, 'instance',
InstancePageStateRecordType, 'instance_page_state', 'user_document',
'camera', CameraRecordType, InstancePresenceRecordType,
'instance_presence'
- [x] Test user preferences
- [x] Manual test isSnapMode and isGridMode and isPenMode
- [ ] Test indexedDb functions
- [x] Add instanceId stuff back
### Change Type
- [x] `major` — Breaking Change
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] Webdriver tests
### Release Notes
- Add a brief release note for your PR here.
2023-06-05 14:11:07 +00:00
|
|
|
export type TLRecord = TLAsset | TLCamera | TLDocument | TLInstance | TLInstancePageState | TLInstancePresence | TLPage | TLPointer | TLShape;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export type TLSchema = StoreSchema<TLRecord, TLStoreProps>;
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export type TLScribble = {
|
|
|
|
points: Vec2dModel[];
|
|
|
|
size: number;
|
2023-06-12 14:04:14 +00:00
|
|
|
color: TLCanvasUiColor;
|
2023-04-25 11:01:25 +00:00
|
|
|
opacity: number;
|
|
|
|
state: SetValue<typeof TL_SCRIBBLE_STATES>;
|
2023-05-19 11:09:13 +00:00
|
|
|
delay: number;
|
2023-04-25 11:01:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// @public
|
2023-05-24 10:48:31 +00:00
|
|
|
export type TLShape = TLDefaultShape | TLUnknownShape;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-03 20:46:53 +00:00
|
|
|
export type TLShapeId = RecordId<TLUnknownShape>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLShapePartial<T extends TLShape = TLShape> = T extends T ? {
|
|
|
|
id: TLShapeId;
|
|
|
|
type: T['type'];
|
|
|
|
props?: Partial<T['props']>;
|
|
|
|
} & Partial<Omit<T, 'id' | 'props' | 'type'>> : never;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLShapeProp = keyof TLShapeProps;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-06 16:15:12 +00:00
|
|
|
export type TLShapeProps = Identity<UnionToIntersection<TLDefaultShape['props']>>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLStore = Store<TLRecord, TLStoreProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLStoreProps = {
|
2023-06-01 18:46:26 +00:00
|
|
|
defaultName: string;
|
2023-04-25 11:01:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLStoreSchema = StoreSchema<TLRecord, TLStoreProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLStoreSnapshot = StoreSnapshot<TLRecord>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLTextShape = TLBaseShape<'text', TLTextShapeProps>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLTextShapeProps = ShapePropsType<typeof textShapeProps>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-24 10:48:31 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export type TLUnknownShape = TLBaseShape<string, object>;
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export type TLVideoAsset = TLBaseAsset<'video', {
|
|
|
|
w: number;
|
|
|
|
h: number;
|
|
|
|
name: string;
|
|
|
|
isAnimated: boolean;
|
|
|
|
mimeType: null | string;
|
|
|
|
src: null | string;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLVideoShape = TLBaseShape<'video', TLVideoShapeProps>;
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
// @public
|
2023-04-25 11:01:25 +00:00
|
|
|
export interface Vec2dModel {
|
|
|
|
// (undocumented)
|
|
|
|
x: number;
|
|
|
|
// (undocumented)
|
|
|
|
y: number;
|
|
|
|
// (undocumented)
|
|
|
|
z?: number;
|
|
|
|
}
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const vec2dModelValidator: T.Validator<Vec2dModel>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-06-12 14:04:14 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const videoShapeMigrations: Migrations;
|
|
|
|
|
2023-06-16 10:33:47 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const videoShapeProps: {
|
|
|
|
w: T.Validator<number>;
|
|
|
|
h: T.Validator<number>;
|
|
|
|
time: T.Validator<number>;
|
|
|
|
playing: T.Validator<boolean>;
|
|
|
|
url: T.Validator<string>;
|
|
|
|
assetId: T.Validator<TLAssetId | null>;
|
|
|
|
};
|
2023-06-12 14:04:14 +00:00
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// (No @packageDocumentation comment for this package)
|
|
|
|
|
|
|
|
```
|