@scrawl-board/board 0.1.0-beta.0 → 0.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +49 -7
- package/dist/browser.js +250 -99
- package/dist/core.d.ts +96 -25
- package/dist/core.js +63 -23
- package/dist/index.d.ts +118 -30
- package/dist/index.js +335 -111
- package/dist/react.d.ts +95 -7
- package/dist/react.js +326 -110
- package/package.json +1 -1
package/dist/core.d.ts
CHANGED
|
@@ -11,6 +11,79 @@ declare function strokeId(value: string): StrokeId;
|
|
|
11
11
|
|
|
12
12
|
/** Wire grammar: `asset:<namespace>:<opaque-id>`. Interpreted only by the Host. */
|
|
13
13
|
type AssetRef = string;
|
|
14
|
+
declare const ASSET_REF_PATTERN: RegExp;
|
|
15
|
+
/** Hard ceiling on a reference's own wire length — independent of any resource limit below. */
|
|
16
|
+
declare const ASSET_REF_MAX_BYTES = 512;
|
|
17
|
+
declare function isAssetRef(value: unknown): value is AssetRef;
|
|
18
|
+
/** Throws on malformed input; use `isAssetRef` where a boolean is wanted instead. */
|
|
19
|
+
declare function assetRef(value: string): AssetRef;
|
|
20
|
+
type AssetKind = "image";
|
|
21
|
+
type AssetPurpose = "render" | "thumbnail" | "export";
|
|
22
|
+
interface AssetResolveRequest {
|
|
23
|
+
ref: AssetRef;
|
|
24
|
+
kind: AssetKind;
|
|
25
|
+
purpose: AssetPurpose;
|
|
26
|
+
signal: AbortSignal;
|
|
27
|
+
}
|
|
28
|
+
interface AssetResolveResult {
|
|
29
|
+
bytes: Uint8Array;
|
|
30
|
+
mediaType: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Host-owned lookup. Scrawl passes only the reference, kind, purpose, and
|
|
34
|
+
* signal — never Document contents, an Extension instance, or credentials.
|
|
35
|
+
* The returned bytes are copied into SDK-owned storage and independently
|
|
36
|
+
* validated before use; a resolver's claimed `mediaType` is never trusted
|
|
37
|
+
* on its own (see `assetValidation.ts`).
|
|
38
|
+
*/
|
|
39
|
+
interface AssetResolver {
|
|
40
|
+
resolve(request: AssetResolveRequest): Promise<AssetResolveResult>;
|
|
41
|
+
}
|
|
42
|
+
interface AssetIngestRequest {
|
|
43
|
+
bytes: Uint8Array;
|
|
44
|
+
mediaType: string;
|
|
45
|
+
name?: string;
|
|
46
|
+
signal: AbortSignal;
|
|
47
|
+
}
|
|
48
|
+
interface AssetIngestResult {
|
|
49
|
+
ref: AssetRef;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Host-owned upload/creation path. Scrawl validates the candidate against
|
|
53
|
+
* SDK limits before calling this, and validates the returned reference
|
|
54
|
+
* before it can enter any command. Cancellation or failure creates no
|
|
55
|
+
* Document object, Op, or history entry.
|
|
56
|
+
*/
|
|
57
|
+
interface AssetIngestor {
|
|
58
|
+
ingest(request: AssetIngestRequest): Promise<AssetIngestResult>;
|
|
59
|
+
}
|
|
60
|
+
type AssetResolutionErrorCode = "resolver-unavailable" | "not-found" | "forbidden" | "offline" | "unsupported-type" | "too-large" | "invalid-content" | "decode-failed" | "budget-exceeded" | "aborted" | "unknown";
|
|
61
|
+
declare class AssetResolutionError extends Error {
|
|
62
|
+
readonly code: AssetResolutionErrorCode;
|
|
63
|
+
readonly retryable: boolean;
|
|
64
|
+
readonly ref?: AssetRef | undefined;
|
|
65
|
+
constructor(code: AssetResolutionErrorCode, retryable: boolean, message: string, ref?: AssetRef | undefined);
|
|
66
|
+
}
|
|
67
|
+
/** Runtime event for a resolution/ingestion failure — never carries credentials or a fetchable location. */
|
|
68
|
+
interface AssetDiagnostic {
|
|
69
|
+
code: AssetResolutionErrorCode;
|
|
70
|
+
ref?: AssetRef;
|
|
71
|
+
objectId: string;
|
|
72
|
+
objectKind: "image" | "custom";
|
|
73
|
+
retryable: boolean;
|
|
74
|
+
}
|
|
75
|
+
declare const ASSET_MAX_ENCODED_BYTES: number;
|
|
76
|
+
declare const ASSET_MAX_DIMENSION_PX = 8192;
|
|
77
|
+
declare const ASSET_MAX_DECODED_MEGAPIXELS = 40;
|
|
78
|
+
declare const ASSET_MAX_CONCURRENT_RESOLUTIONS = 6;
|
|
79
|
+
declare const ASSET_CACHE_BYTES_DEFAULT: number;
|
|
80
|
+
declare const ASSET_CACHE_BYTES_MIN: number;
|
|
81
|
+
declare const ASSET_CACHE_BYTES_MAX: number;
|
|
82
|
+
declare const ASSET_EXPORT_MAX_ENCODED_BYTES: number;
|
|
83
|
+
declare const ASSET_EXPORT_MAX_DECODED_MEGAPIXELS = 100;
|
|
84
|
+
declare const SUPPORTED_ASSET_MEDIA_TYPES: readonly ["image/png", "image/jpeg", "image/webp"];
|
|
85
|
+
type SupportedAssetMediaType = (typeof SUPPORTED_ASSET_MEDIA_TYPES)[number];
|
|
86
|
+
declare function clampAssetCacheBytes(value: number | undefined): number;
|
|
14
87
|
|
|
15
88
|
type Mat2x3 = [number, number, number, number, number, number];
|
|
16
89
|
declare const IDENTITY: Mat2x3;
|
|
@@ -69,6 +142,7 @@ interface CustomBoardObject {
|
|
|
69
142
|
};
|
|
70
143
|
props: JsonValue;
|
|
71
144
|
}
|
|
145
|
+
declare function cloneCustomObject(object: CustomBoardObject): CustomBoardObject;
|
|
72
146
|
/**
|
|
73
147
|
* The read-only view handed to `describe`. Deep-readonly by construction
|
|
74
148
|
* (not derived via a shallow `Readonly<>`) because `describe` must treat its
|
|
@@ -106,7 +180,7 @@ interface CustomObjectDefinition<Props extends JsonValue = JsonValue> {
|
|
|
106
180
|
parse(input: unknown, schemaVersion: number): Props;
|
|
107
181
|
/** One pure, synchronous step per consecutive schema version. */
|
|
108
182
|
migrate?: Readonly<Record<number, (oldProps: JsonValue) => JsonValue>>;
|
|
109
|
-
describe(object: ReadonlyCustomObject<Props>, context: ObjectDescribeContext): BoardScene
|
|
183
|
+
describe(object: ReadonlyCustomObject<Props>, context: ObjectDescribeContext): BoardScene;
|
|
110
184
|
}
|
|
111
185
|
interface SceneNodeBase {
|
|
112
186
|
key: string;
|
|
@@ -138,9 +212,9 @@ interface SceneText extends SceneNodeBase {
|
|
|
138
212
|
}
|
|
139
213
|
interface SceneGroup extends SceneNodeBase {
|
|
140
214
|
kind: "group";
|
|
141
|
-
children: readonly BoardScene
|
|
215
|
+
children: readonly BoardScene[];
|
|
142
216
|
}
|
|
143
|
-
interface ScenePath
|
|
217
|
+
interface ScenePath extends SceneNodeBase {
|
|
144
218
|
kind: "path";
|
|
145
219
|
/** SVG-style path data, board-local coordinates. */
|
|
146
220
|
d: string;
|
|
@@ -173,7 +247,7 @@ interface SceneEllipse extends SceneNodeBase {
|
|
|
173
247
|
stroke?: string;
|
|
174
248
|
strokeWidth?: number;
|
|
175
249
|
}
|
|
176
|
-
type BoardScene
|
|
250
|
+
type BoardScene = SceneGroup | ScenePath | SceneText | SceneImage | SceneRect | SceneEllipse;
|
|
177
251
|
type ToolCursor = "default" | "crosshair" | "pointer" | "grab" | "grabbing" | "text";
|
|
178
252
|
type ToolCancelReason = "escape-key" | "tool-switched" | "pointer-lost" | "error";
|
|
179
253
|
interface InputModifiers {
|
|
@@ -269,7 +343,7 @@ interface ToolCapabilities {
|
|
|
269
343
|
};
|
|
270
344
|
/** Session-only geometry — never enters Document/history/persistence/collaboration. */
|
|
271
345
|
preview: {
|
|
272
|
-
set(scene: BoardScene
|
|
346
|
+
set(scene: BoardScene): void;
|
|
273
347
|
clear(): void;
|
|
274
348
|
};
|
|
275
349
|
/** Constructs, validates, and commits one atomic command; controller derives Ops. */
|
|
@@ -279,6 +353,15 @@ interface ToolCapabilities {
|
|
|
279
353
|
cancel(): void;
|
|
280
354
|
};
|
|
281
355
|
}
|
|
356
|
+
interface ExtensionDiagnostic {
|
|
357
|
+
extensionId: ExtensionId;
|
|
358
|
+
phase: "parse" | "migrate" | "describe" | "tool-lifecycle" | "react-companion" | "asset-resolution";
|
|
359
|
+
toolId?: ToolId;
|
|
360
|
+
objectId?: string;
|
|
361
|
+
objectType?: ObjectType;
|
|
362
|
+
recoverable: boolean;
|
|
363
|
+
cause: unknown;
|
|
364
|
+
}
|
|
282
365
|
|
|
283
366
|
/** Who holds a lock. Stored on the item so only they can take it off. */
|
|
284
367
|
interface LockHolder {
|
|
@@ -489,7 +572,6 @@ declare function measureTable(table: TableBlock): {
|
|
|
489
572
|
width: number;
|
|
490
573
|
height: number;
|
|
491
574
|
};
|
|
492
|
-
declare const BOARD_COLOR = "#FFFFFF";
|
|
493
575
|
declare const FOG_COLOR = "#FFFFFF";
|
|
494
576
|
/**
|
|
495
577
|
* An imported image block on the board plane.
|
|
@@ -1048,6 +1130,11 @@ interface ExtensionRegistry {
|
|
|
1048
1130
|
* isn't in it), Custom objects still export via the standard fallback
|
|
1049
1131
|
* placeholder (`fallback.bounds`/`label`), never silently dropped.
|
|
1050
1132
|
*
|
|
1133
|
+
* `backgroundColor` should be the Host's actual resolved `boardTheme.surface`
|
|
1134
|
+
* so an export matches what was on screen; defaults to the theme system's
|
|
1135
|
+
* own light-preset default when the caller doesn't have one on hand. The
|
|
1136
|
+
* board's reference grid, if any, is a screen-only aid and never exported.
|
|
1137
|
+
*
|
|
1051
1138
|
* `resolvedAssets` (ticket #23) maps an Asset reference to an already-
|
|
1052
1139
|
* resolved `data:` URI — see `assetExport.ts`'s `exportDocumentSVGWithAssets`,
|
|
1053
1140
|
* which is the only intended caller that ever passes one. Without it, every
|
|
@@ -1055,30 +1142,14 @@ interface ExtensionRegistry {
|
|
|
1055
1142
|
* placeholder instead of guessing at a URL; a legacy `src`-backed image is
|
|
1056
1143
|
* unaffected either way.
|
|
1057
1144
|
*/
|
|
1058
|
-
declare function documentToSVG(doc: SerializedDocument, now?: number, registry?: ExtensionRegistry, resolvedAssets?: ReadonlyMap<AssetRef, string>): string;
|
|
1145
|
+
declare function documentToSVG(doc: SerializedDocument, now?: number, registry?: ExtensionRegistry, backgroundColor?: string, resolvedAssets?: ReadonlyMap<AssetRef, string>): string;
|
|
1059
1146
|
|
|
1060
1147
|
declare const SDK_PACKAGE_NAME = "@scrawl-board/board";
|
|
1061
1148
|
declare const SDK_DEVELOPMENT_VERSION = "0.0.0-development";
|
|
1062
1149
|
|
|
1063
|
-
type BoardBounds = {
|
|
1064
|
-
minX: number;
|
|
1065
|
-
minY: number;
|
|
1066
|
-
maxX: number;
|
|
1067
|
-
maxY: number;
|
|
1068
|
-
};
|
|
1069
|
-
type ScenePath = {
|
|
1070
|
-
id: string;
|
|
1071
|
-
color: string;
|
|
1072
|
-
width: number;
|
|
1073
|
-
points: readonly BoardPoint[];
|
|
1074
|
-
};
|
|
1075
|
-
type BoardScene = {
|
|
1076
|
-
bounds: BoardBounds;
|
|
1077
|
-
paths: readonly ScenePath[];
|
|
1078
|
-
};
|
|
1079
1150
|
type BoardStroke = Stroke;
|
|
1080
1151
|
type SerializedBoardStroke = SerializedStroke;
|
|
1081
1152
|
type SerializedBoardDocument = CurrentSerializedDocument;
|
|
1082
1153
|
|
|
1083
|
-
export { AddImageCommand, AddNoteCommand, AddStrokesCommand, AddTableCommand, AddTextCommand, AddTimerCommand,
|
|
1084
|
-
export type { BBox,
|
|
1154
|
+
export { ASSET_CACHE_BYTES_DEFAULT, ASSET_CACHE_BYTES_MAX, ASSET_CACHE_BYTES_MIN, ASSET_EXPORT_MAX_DECODED_MEGAPIXELS, ASSET_EXPORT_MAX_ENCODED_BYTES, ASSET_MAX_CONCURRENT_RESOLUTIONS, ASSET_MAX_DECODED_MEGAPIXELS, ASSET_MAX_DIMENSION_PX, ASSET_MAX_ENCODED_BYTES, ASSET_REF_MAX_BYTES, ASSET_REF_PATTERN, AddImageCommand, AddNoteCommand, AddStrokesCommand, AddTableCommand, AddTextCommand, AddTimerCommand, AssetResolutionError, BEACON_INSET, BoardDocument, CURRENT_DOCUMENT_SCHEMA_VERSION, ClusterStore, DeleteImageCommand, DeleteNoteCommand, DeleteStrokesCommand, DeleteTableCommand, DeleteTextCommand, DeleteTimerCommand, DocumentRecoveryError, END_TAPER, ERASE_THRESHOLD, EraseCommand, FOG_COLOR, HIGHLIGHT_COLORS, History, IDENTITY, INK_COLORS, LockItemsCommand, MIN_WIDTH_FACTOR, NOTE_COLORS, NOTE_DEFAULT_SIZE, NOTE_DEFAULT_Z, NOTE_MAX_Z, NOTE_MIN_Z, NOTE_PEEL_STEP, SDK_DEVELOPMENT_VERSION, SDK_PACKAGE_NAME, STAMPS, STAMP_SIZE, SUPPORTED_ASSET_MEDIA_TYPES, SpatialIndex, TABLE_DEFAULT_CELL_HEIGHT, TABLE_DEFAULT_CELL_WIDTH, TABLE_DEFAULT_FONT_SIZE, TEXT_DEFAULT_SIZE, TIMER_DEFAULT_DURATION_MS, TIMER_DEFAULT_SIZE, TIMER_PRESETS_MS, TransformCommand, UpdateImageCommand, UpdateNoteCommand, UpdateTableCommand, UpdateTextCommand, UpdateTimerCommand, apply, applyItemLock, assetRef, avgScale, canUnlockItem, changeToOps, clampAssetCacheBytes, cloneCustomObject, cloneImage, cloneNote, cloneStroke, cloneTable, cloneText, cloneTimer, documentId, documentToSVG, formatTimer, invert, isAssetRef, isIdentity, isStampKind, loadDocumentBytes, measureTable, measureTextBlock, migrateDocument, mul, pauseTimer, placePresenceBeacon, ribbonEdges, rotationAbout, scalingAbout, searchBoard, serializeDocument, serializeLock, serializeStroke, setTimerDuration, stampDataUrl, startTimer, strokeId, timerExpired, timerRemaining, toggleTimer, translation };
|
|
1155
|
+
export type { AssetDiagnostic, AssetIngestRequest, AssetIngestResult, AssetIngestor, AssetKind, AssetPurpose, AssetRef, AssetResolutionErrorCode, AssetResolveRequest, AssetResolveResult, AssetResolver, BBox, BoardKeyInput, BoardPoint, BoardPointerInput, BoardScene, BoardStroke, ClusterIdFactory, Command, CommandKind, CurrentSerializedDocument, CurrentSerializedStroke, CustomBoardObject, CustomObjectAddInput, CustomObjectDefinition, CustomTool, CustomToolDefinition, DocumentChange, DocumentId, DocumentLoadResult, DocumentRecoveryCode, ExtensionCommand, ExtensionDiagnostic, ExtensionHitResult, ExtensionId, ExtensionRequirement, ImageBlock, InputModifiers, JsonObject, JsonValue, KitchenTimer, LockHolder, LockTarget, Lockable, Mat2x3, NoteVote, ObjectDescribeContext, ObjectIntent, ObjectType, Op, OpCollection, PresencePlacement, QueryableBoardObject, ReadonlyCustomObject, RibbonEdgePoint, SceneEllipse, SceneGroup, SceneImage, ScenePath, SceneRect, SceneText, ScrawlExtension, SearchHit, SearchHitKind, SearchableBoard, SearchableComment, SerializedBoardDocument, SerializedBoardStroke, SerializedPoint, SerializedStroke, StampKind, StickyNote, Stroke, StrokeId, StrokePoint, StrokeTool, SupportedAssetMediaType, TableBlock, TextBlock, ToolCancelReason, ToolCapabilities, ToolCursor, ToolId, ViewportInset };
|
package/dist/core.js
CHANGED
|
@@ -1,10 +1,44 @@
|
|
|
1
|
-
//#region src/core
|
|
1
|
+
//#region src/core/shapes/assets.ts
|
|
2
2
|
var ASSET_REF_PATTERN = /^asset:[a-z0-9](?:[a-z0-9.-]{0,61}[a-z0-9])?:[A-Za-z0-9._~-]+$/;
|
|
3
|
+
/** Hard ceiling on a reference's own wire length — independent of any resource limit below. */
|
|
4
|
+
var ASSET_REF_MAX_BYTES = 512;
|
|
3
5
|
function isAssetRef(value) {
|
|
4
6
|
return typeof value === "string" && ASSET_REF_PATTERN.test(value) && new TextEncoder().encode(value).length <= 512;
|
|
5
7
|
}
|
|
8
|
+
/** Throws on malformed input; use `isAssetRef` where a boolean is wanted instead. */
|
|
9
|
+
function assetRef(value) {
|
|
10
|
+
if (!isAssetRef(value)) throw new TypeError(`Not a well-formed AssetRef: ${JSON.stringify(value)}`);
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
var AssetResolutionError = class extends Error {
|
|
14
|
+
constructor(code, retryable, message, ref) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.retryable = retryable;
|
|
18
|
+
this.ref = ref;
|
|
19
|
+
this.name = "AssetResolutionError";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var ASSET_MAX_ENCODED_BYTES = 20 * 1024 * 1024;
|
|
23
|
+
var ASSET_MAX_DIMENSION_PX = 8192;
|
|
24
|
+
var ASSET_MAX_DECODED_MEGAPIXELS = 40;
|
|
25
|
+
var ASSET_MAX_CONCURRENT_RESOLUTIONS = 6;
|
|
26
|
+
var ASSET_CACHE_BYTES_DEFAULT = 256 * 1024 * 1024;
|
|
27
|
+
var ASSET_CACHE_BYTES_MIN = 64 * 1024 * 1024;
|
|
28
|
+
var ASSET_CACHE_BYTES_MAX = 512 * 1024 * 1024;
|
|
29
|
+
var ASSET_EXPORT_MAX_ENCODED_BYTES = 100 * 1024 * 1024;
|
|
30
|
+
var ASSET_EXPORT_MAX_DECODED_MEGAPIXELS = 100;
|
|
31
|
+
var SUPPORTED_ASSET_MEDIA_TYPES = [
|
|
32
|
+
"image/png",
|
|
33
|
+
"image/jpeg",
|
|
34
|
+
"image/webp"
|
|
35
|
+
];
|
|
36
|
+
function clampAssetCacheBytes(value) {
|
|
37
|
+
if (value === void 0 || !Number.isFinite(value)) return ASSET_CACHE_BYTES_DEFAULT;
|
|
38
|
+
return Math.min(ASSET_CACHE_BYTES_MAX, Math.max(ASSET_CACHE_BYTES_MIN, Math.floor(value)));
|
|
39
|
+
}
|
|
6
40
|
//#endregion
|
|
7
|
-
//#region src/core
|
|
41
|
+
//#region src/core/document/identifiers.ts
|
|
8
42
|
function documentId(value) {
|
|
9
43
|
if (!value) throw new TypeError("DocumentId cannot be empty");
|
|
10
44
|
return value;
|
|
@@ -14,7 +48,7 @@ function strokeId(value) {
|
|
|
14
48
|
return value;
|
|
15
49
|
}
|
|
16
50
|
//#endregion
|
|
17
|
-
//#region src/document-schema.ts
|
|
51
|
+
//#region src/core/document/document-schema.ts
|
|
18
52
|
var CURRENT_DOCUMENT_SCHEMA_VERSION = 1;
|
|
19
53
|
var DocumentRecoveryError = class extends Error {
|
|
20
54
|
constructor(code, message, originalBytes, path) {
|
|
@@ -222,7 +256,7 @@ function validation(message, path) {
|
|
|
222
256
|
return new DocumentRecoveryError("DOCUMENT_VALIDATION_FAILED", message, void 0, path);
|
|
223
257
|
}
|
|
224
258
|
//#endregion
|
|
225
|
-
//#region src/core
|
|
259
|
+
//#region src/core/shapes/affine2d.ts
|
|
226
260
|
var IDENTITY = [
|
|
227
261
|
1,
|
|
228
262
|
0,
|
|
@@ -306,7 +340,7 @@ function avgScale(m) {
|
|
|
306
340
|
return (Math.hypot(m[0], m[1]) + Math.hypot(m[2], m[3])) / 2;
|
|
307
341
|
}
|
|
308
342
|
//#endregion
|
|
309
|
-
//#region src/core
|
|
343
|
+
//#region src/core/document/boardSearch.ts
|
|
310
344
|
function hay(s) {
|
|
311
345
|
return s.toLowerCase();
|
|
312
346
|
}
|
|
@@ -371,7 +405,7 @@ function searchBoard(query, board) {
|
|
|
371
405
|
return hits;
|
|
372
406
|
}
|
|
373
407
|
//#endregion
|
|
374
|
-
//#region src/core
|
|
408
|
+
//#region src/core/shapes/types.ts
|
|
375
409
|
/** Erasure level at which a point counts as fully erased. */
|
|
376
410
|
var ERASE_THRESHOLD = .95;
|
|
377
411
|
function cloneStroke(stroke) {
|
|
@@ -442,13 +476,12 @@ function measureTable(table) {
|
|
|
442
476
|
height: table.rowHeights.reduce((sum, h) => sum + h, 0)
|
|
443
477
|
};
|
|
444
478
|
}
|
|
445
|
-
var BOARD_COLOR = "#FFFFFF";
|
|
446
479
|
var FOG_COLOR = "#FFFFFF";
|
|
447
480
|
function cloneImage(img) {
|
|
448
481
|
return { ...img };
|
|
449
482
|
}
|
|
450
483
|
//#endregion
|
|
451
|
-
//#region src/core
|
|
484
|
+
//#region src/core/document/clusterStore.ts
|
|
452
485
|
/** A stroke joins a cluster last written to within this window at full reach. */
|
|
453
486
|
var RECENT_MS = 8e3;
|
|
454
487
|
/** Older clusters are still joinable, at half the gap threshold. */
|
|
@@ -619,7 +652,7 @@ function clamp$1(v, lo, hi) {
|
|
|
619
652
|
return Math.min(hi, Math.max(lo, v));
|
|
620
653
|
}
|
|
621
654
|
//#endregion
|
|
622
|
-
//#region src/core
|
|
655
|
+
//#region src/core/shapes/extensionTypes.ts
|
|
623
656
|
function cloneCustomObject(object) {
|
|
624
657
|
return {
|
|
625
658
|
...object,
|
|
@@ -629,7 +662,7 @@ function cloneCustomObject(object) {
|
|
|
629
662
|
};
|
|
630
663
|
}
|
|
631
664
|
//#endregion
|
|
632
|
-
//#region src/core
|
|
665
|
+
//#region src/core/shapes/kitchenTimer.ts
|
|
633
666
|
var TIMER_DEFAULT_SIZE = 12;
|
|
634
667
|
var TIMER_DEFAULT_DURATION_MS = 300 * 1e3;
|
|
635
668
|
var TIMER_PRESETS_MS = [
|
|
@@ -686,7 +719,7 @@ function formatTimer(ms) {
|
|
|
686
719
|
return `${Math.floor(total / 60)}:${(total % 60).toString().padStart(2, "0")}`;
|
|
687
720
|
}
|
|
688
721
|
//#endregion
|
|
689
|
-
//#region src/core
|
|
722
|
+
//#region src/core/shapes/itemLock.ts
|
|
690
723
|
/**
|
|
691
724
|
* Apply or clear a lock in place. Unlock always drops the holder so a stale
|
|
692
725
|
* name cannot linger on an unlocked item.
|
|
@@ -723,7 +756,7 @@ function serializeLock(item) {
|
|
|
723
756
|
};
|
|
724
757
|
}
|
|
725
758
|
//#endregion
|
|
726
|
-
//#region src/core
|
|
759
|
+
//#region src/core/document/document.ts
|
|
727
760
|
/**
|
|
728
761
|
* The one place a live Stroke becomes its wire representation — in
|
|
729
762
|
* particular, points collapse from {x,y,pressure,erase?} objects into
|
|
@@ -1282,7 +1315,7 @@ function computeBBox(stroke) {
|
|
|
1282
1315
|
return world;
|
|
1283
1316
|
}
|
|
1284
1317
|
//#endregion
|
|
1285
|
-
//#region src/core
|
|
1318
|
+
//#region src/core/commands/commands.ts
|
|
1286
1319
|
/** One drawing action — a marker stroke, or a shape's strokes as one unit. */
|
|
1287
1320
|
var AddStrokesCommand = class {
|
|
1288
1321
|
constructor(strokes) {
|
|
@@ -1581,7 +1614,7 @@ var LockItemsCommand = class {
|
|
|
1581
1614
|
}
|
|
1582
1615
|
};
|
|
1583
1616
|
//#endregion
|
|
1584
|
-
//#region src/core
|
|
1617
|
+
//#region src/core/history/history.ts
|
|
1585
1618
|
var LIMIT = 200;
|
|
1586
1619
|
var History = class {
|
|
1587
1620
|
constructor(doc) {
|
|
@@ -1642,7 +1675,7 @@ var History = class {
|
|
|
1642
1675
|
}
|
|
1643
1676
|
};
|
|
1644
1677
|
//#endregion
|
|
1645
|
-
//#region src/core
|
|
1678
|
+
//#region src/core/events/ops.ts
|
|
1646
1679
|
var ADDED = [
|
|
1647
1680
|
["added", "strokes"],
|
|
1648
1681
|
["notesAdded", "notes"],
|
|
@@ -1696,7 +1729,7 @@ function changeToOps(change, restoring = false) {
|
|
|
1696
1729
|
return ops;
|
|
1697
1730
|
}
|
|
1698
1731
|
//#endregion
|
|
1699
|
-
//#region src/core
|
|
1732
|
+
//#region src/core/shapes/ribbonEdges.ts
|
|
1700
1733
|
var MIN_WIDTH_FACTOR = .35;
|
|
1701
1734
|
var END_TAPER = .55;
|
|
1702
1735
|
function ribbonEdges(points, baseWidth) {
|
|
@@ -1728,7 +1761,7 @@ function ribbonEdges(points, baseWidth) {
|
|
|
1728
1761
|
return out;
|
|
1729
1762
|
}
|
|
1730
1763
|
//#endregion
|
|
1731
|
-
//#region src/core
|
|
1764
|
+
//#region src/core/document/spatialIndex.ts
|
|
1732
1765
|
var CELL = 8;
|
|
1733
1766
|
var SpatialIndex = class {
|
|
1734
1767
|
constructor(doc) {
|
|
@@ -1801,7 +1834,7 @@ function cellsOf(box) {
|
|
|
1801
1834
|
return keys;
|
|
1802
1835
|
}
|
|
1803
1836
|
//#endregion
|
|
1804
|
-
//#region src/core
|
|
1837
|
+
//#region src/core/shapes/stamps.ts
|
|
1805
1838
|
var STAMP_SIZE = 6;
|
|
1806
1839
|
var STAMPS = [
|
|
1807
1840
|
{
|
|
@@ -1850,7 +1883,7 @@ function isStampKind(value) {
|
|
|
1850
1883
|
return typeof value === "string" && STAMPS.some((s) => s.kind === value);
|
|
1851
1884
|
}
|
|
1852
1885
|
//#endregion
|
|
1853
|
-
//#region src/
|
|
1886
|
+
//#region src/collaboration/presence/presence.ts
|
|
1854
1887
|
/** Keep beacons clear of typical chrome at the top and bottom of the Board. */
|
|
1855
1888
|
var BEACON_INSET = {
|
|
1856
1889
|
top: 72,
|
|
@@ -1886,7 +1919,7 @@ function clamp(value, min, max) {
|
|
|
1886
1919
|
return Math.min(max, Math.max(min, value));
|
|
1887
1920
|
}
|
|
1888
1921
|
//#endregion
|
|
1889
|
-
//#region src/
|
|
1922
|
+
//#region src/persistence/serialization/svg.ts
|
|
1890
1923
|
/** Matches the key light used by the board shader and note shadows. */
|
|
1891
1924
|
var LIGHT = {
|
|
1892
1925
|
x: -.25,
|
|
@@ -1896,12 +1929,19 @@ var LIGHT = {
|
|
|
1896
1929
|
var MARGIN = 4;
|
|
1897
1930
|
var NOTE_FONT_RATIO = 44 / 512;
|
|
1898
1931
|
var NOTE_PAD_RATIO = 40 / 512;
|
|
1932
|
+
/** Matches the theme system's light-preset `boardSurface` default (theme.ts) — kept in sync manually, since core-internal stays decoupled from the theme layer. */
|
|
1933
|
+
var DEFAULT_BACKGROUND_COLOR = "#f5f5f3";
|
|
1899
1934
|
/**
|
|
1900
1935
|
* `registry` is optional and only enables rendering Custom objects through
|
|
1901
1936
|
* their own `describe()` — without it (or for an object whose extension
|
|
1902
1937
|
* isn't in it), Custom objects still export via the standard fallback
|
|
1903
1938
|
* placeholder (`fallback.bounds`/`label`), never silently dropped.
|
|
1904
1939
|
*
|
|
1940
|
+
* `backgroundColor` should be the Host's actual resolved `boardTheme.surface`
|
|
1941
|
+
* so an export matches what was on screen; defaults to the theme system's
|
|
1942
|
+
* own light-preset default when the caller doesn't have one on hand. The
|
|
1943
|
+
* board's reference grid, if any, is a screen-only aid and never exported.
|
|
1944
|
+
*
|
|
1905
1945
|
* `resolvedAssets` (ticket #23) maps an Asset reference to an already-
|
|
1906
1946
|
* resolved `data:` URI — see `assetExport.ts`'s `exportDocumentSVGWithAssets`,
|
|
1907
1947
|
* which is the only intended caller that ever passes one. Without it, every
|
|
@@ -1909,7 +1949,7 @@ var NOTE_PAD_RATIO = 40 / 512;
|
|
|
1909
1949
|
* placeholder instead of guessing at a URL; a legacy `src`-backed image is
|
|
1910
1950
|
* unaffected either way.
|
|
1911
1951
|
*/
|
|
1912
|
-
function documentToSVG(doc, now = 0, registry, resolvedAssets) {
|
|
1952
|
+
function documentToSVG(doc, now = 0, registry, backgroundColor = DEFAULT_BACKGROUND_COLOR, resolvedAssets) {
|
|
1913
1953
|
const notes = doc.notes ?? [];
|
|
1914
1954
|
const texts = doc.textBlocks ?? [];
|
|
1915
1955
|
const tables = doc.tables ?? [];
|
|
@@ -1922,7 +1962,7 @@ function documentToSVG(doc, now = 0, registry, resolvedAssets) {
|
|
|
1922
1962
|
const highlights = doc.strokes.filter((s) => s.tool === "highlighter");
|
|
1923
1963
|
const ink = doc.strokes.filter((s) => s.tool !== "highlighter");
|
|
1924
1964
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${view}">\n<defs>\n${defs}\n</defs>\n${[
|
|
1925
|
-
`<rect x="${fmt(bounds.minX)}" y="${fmt(bounds.minY)}" width="${fmt(bounds.width)}" height="${fmt(bounds.height)}" fill="${
|
|
1965
|
+
`<rect x="${fmt(bounds.minX)}" y="${fmt(bounds.minY)}" width="${fmt(bounds.width)}" height="${fmt(bounds.height)}" fill="${backgroundColor}"/>`,
|
|
1926
1966
|
...images.map((image) => imageToElement(image, resolvedAssets)),
|
|
1927
1967
|
...tables.map(tableToGroup),
|
|
1928
1968
|
...highlights.flatMap(strokeToPaths),
|
|
@@ -2250,4 +2290,4 @@ function fmt(n) {
|
|
|
2250
2290
|
var SDK_PACKAGE_NAME = "@scrawl-board/board";
|
|
2251
2291
|
var SDK_DEVELOPMENT_VERSION = "0.0.0-development";
|
|
2252
2292
|
//#endregion
|
|
2253
|
-
export { AddImageCommand, AddNoteCommand, AddStrokesCommand, AddTableCommand, AddTextCommand, AddTimerCommand,
|
|
2293
|
+
export { ASSET_CACHE_BYTES_DEFAULT, ASSET_CACHE_BYTES_MAX, ASSET_CACHE_BYTES_MIN, ASSET_EXPORT_MAX_DECODED_MEGAPIXELS, ASSET_EXPORT_MAX_ENCODED_BYTES, ASSET_MAX_CONCURRENT_RESOLUTIONS, ASSET_MAX_DECODED_MEGAPIXELS, ASSET_MAX_DIMENSION_PX, ASSET_MAX_ENCODED_BYTES, ASSET_REF_MAX_BYTES, ASSET_REF_PATTERN, AddImageCommand, AddNoteCommand, AddStrokesCommand, AddTableCommand, AddTextCommand, AddTimerCommand, AssetResolutionError, BEACON_INSET, BoardDocument, CURRENT_DOCUMENT_SCHEMA_VERSION, ClusterStore, DeleteImageCommand, DeleteNoteCommand, DeleteStrokesCommand, DeleteTableCommand, DeleteTextCommand, DeleteTimerCommand, DocumentRecoveryError, END_TAPER, ERASE_THRESHOLD, EraseCommand, FOG_COLOR, HIGHLIGHT_COLORS, History, IDENTITY, INK_COLORS, LockItemsCommand, MIN_WIDTH_FACTOR, NOTE_COLORS, NOTE_DEFAULT_SIZE, NOTE_DEFAULT_Z, NOTE_MAX_Z, NOTE_MIN_Z, NOTE_PEEL_STEP, SDK_DEVELOPMENT_VERSION, SDK_PACKAGE_NAME, STAMPS, STAMP_SIZE, SUPPORTED_ASSET_MEDIA_TYPES, SpatialIndex, TABLE_DEFAULT_CELL_HEIGHT, TABLE_DEFAULT_CELL_WIDTH, TABLE_DEFAULT_FONT_SIZE, TEXT_DEFAULT_SIZE, TIMER_DEFAULT_DURATION_MS, TIMER_DEFAULT_SIZE, TIMER_PRESETS_MS, TransformCommand, UpdateImageCommand, UpdateNoteCommand, UpdateTableCommand, UpdateTextCommand, UpdateTimerCommand, apply, applyItemLock, assetRef, avgScale, canUnlockItem, changeToOps, clampAssetCacheBytes, cloneCustomObject, cloneImage, cloneNote, cloneStroke, cloneTable, cloneText, cloneTimer, documentId, documentToSVG, formatTimer, invert, isAssetRef, isIdentity, isStampKind, loadDocumentBytes, measureTable, measureTextBlock, migrateDocument, mul, pauseTimer, placePresenceBeacon, ribbonEdges, rotationAbout, scalingAbout, searchBoard, serializeDocument, serializeLock, serializeStroke, setTimerDuration, stampDataUrl, startTimer, strokeId, timerExpired, timerRemaining, toggleTimer, translation };
|