@mocanvas/mocanvas 1.0.0 → 4.0.0

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.
@@ -0,0 +1,54 @@
1
+ import { normalizeLoadedRecords } from '@mocanvas/editor';
2
+ import { serializeTldrFile, parseTldrFile } from '@mocanvas/store';
3
+
4
+ // src/file.ts
5
+ function serializeMocanvasFile(editor) {
6
+ const snapshot = editor.store.getStoreSnapshot("document");
7
+ return serializeTldrFile(snapshot.schema, Object.values(snapshot.store));
8
+ }
9
+ function loadMocanvasFile(editor, json) {
10
+ const parsed = parseTldrFile(json);
11
+ if (!parsed.ok) return { ...parsed, warnings: [] };
12
+ const { records, warnings } = normalizeLoadedRecords(parsed.records, { shapeUtils: editor.shapeUtils });
13
+ const store = {};
14
+ for (const r of records) store[r.id] = r;
15
+ editor.run(
16
+ () => {
17
+ editor.store.loadStoreSnapshot({ schema: parsed.schema, store });
18
+ },
19
+ { history: "ignore" }
20
+ );
21
+ editor.history.clear();
22
+ const pages = editor.getPages();
23
+ const current = editor.getCurrentPageId();
24
+ if (pages.length && !pages.some((p) => p.id === current)) editor.setCurrentPage(pages[0].id);
25
+ else editor.setCurrentPage(editor.getCurrentPageId());
26
+ editor.zoomToFit();
27
+ for (const warning of warnings) console.warn(`mocanvas: ${warning}`);
28
+ return { ...parsed, records, warnings };
29
+ }
30
+ var TLDRAW_FILE_EXTENSION = ".tldr";
31
+ function parseTldrawJsonFile({ json, schema }) {
32
+ const parsed = parseTldrFile(json);
33
+ if (parsed.ok) return { ok: true, value: { schema: parsed.schema, records: parsed.records } };
34
+ switch (parsed.error) {
35
+ case "v1File":
36
+ return { ok: false, error: { type: "v1File", data: parsed.cause ?? null } };
37
+ case "invalidRecords":
38
+ return { ok: false, error: { type: "invalidRecords", cause: parsed.cause ?? null } };
39
+ case "futureVersion":
40
+ return { ok: false, error: { type: "fileFormatVersionTooNew", version: Number.NaN } };
41
+ default:
42
+ return { ok: false, error: { type: "notATldrawFile", cause: parsed.cause ?? null } };
43
+ }
44
+ }
45
+ async function serializeTldrawJson(editor) {
46
+ return serializeMocanvasFile(editor);
47
+ }
48
+ async function serializeTldrawJsonBlob(editor) {
49
+ return new Blob([await serializeTldrawJson(editor)], { type: "application/json" });
50
+ }
51
+
52
+ export { TLDRAW_FILE_EXTENSION, loadMocanvasFile, parseTldrawJsonFile, serializeMocanvasFile, serializeTldrawJson, serializeTldrawJsonBlob };
53
+ //# sourceMappingURL=chunk-GYF6AY4N.js.map
54
+ //# sourceMappingURL=chunk-GYF6AY4N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/file.ts"],"names":[],"mappings":"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","file":"chunk-GYF6AY4N.js","sourcesContent":["import type { TldrFile } from \"@mocanvas/store\"\nimport { normalizeLoadedRecords, type Editor } from \"@mocanvas/editor\"\nimport { parseTldrFile, serializeTldrFile, type ParseTldrFileResult } from \"@mocanvas/store\"\n\n/** Serialize the editor's document to `.tldr` JSON text. */\n/**\n * A parsed `.tldr` file: the schema it was written under, and its records.\n *\n * The documented name for what `serializeMocanvasFile` produces and\n * `loadMocanvasFile` accepts.\n */\nexport type TldrawFile = TldrFile\n\nexport function serializeMocanvasFile(editor: Editor): string {\n const snapshot = editor.store.getStoreSnapshot(\"document\")\n return serializeTldrFile(snapshot.schema, Object.values(snapshot.store))\n}\n\n/**\n * The parse result plus whatever the load could not read cleanly.\n *\n * `warnings` is always present (empty when the file needed nothing unusual)\n * and is worth surfacing: it names shapes whose props were repaired, segments\n * that had to be dropped, and shape types with no registered util.\n */\nexport type LoadMocanvasFileResult = ParseTldrFileResult & { warnings: string[] }\n\n/**\n * Load a `.tldr` file (text or parsed JSON) into the editor, replacing the\n * document.\n *\n * Records are normalized before they reach the store, so shapes written by\n * another generation of the format — a rich-text label, a packed freehand\n * path, a prop this build did not exist for — arrive in the form the shape\n * utils expect. `records` in the result are the normalized ones.\n */\nexport function loadMocanvasFile(editor: Editor, json: unknown): LoadMocanvasFileResult {\n const parsed = parseTldrFile(json)\n if (!parsed.ok) return { ...parsed, warnings: [] }\n const { records, warnings } = normalizeLoadedRecords(parsed.records, { shapeUtils: editor.shapeUtils })\n const store: Record<string, unknown> = {}\n for (const r of records) store[r.id] = r\n editor.run(\n () => {\n editor.store.loadStoreSnapshot({ schema: parsed.schema, store: store as never })\n },\n { history: \"ignore\" },\n )\n editor.history.clear()\n // The instance record may point at a page that no longer exists.\n const pages = editor.getPages()\n const current = editor.getCurrentPageId()\n if (pages.length && !pages.some((p) => p.id === current)) editor.setCurrentPage(pages[0]!.id)\n else editor.setCurrentPage(editor.getCurrentPageId())\n editor.zoomToFit()\n for (const warning of warnings) console.warn(`mocanvas: ${warning}`)\n return { ...parsed, records, warnings }\n}\n\n// ---------------------------------------------------------------------------\n// The documented `.tldr` surface\n// ---------------------------------------------------------------------------\n// The same three operations as above under the names the file format is\n// documented by, plus the error shape a parse failure reports. They are aliases\n// rather than reimplementations: one parser, one serializer, two spellings.\n\n/** The extension a saved document is written under, including the dot. */\nexport const TLDRAW_FILE_EXTENSION = \".tldr\"\n\n/**\n * Why a file could not be read.\n *\n * A discriminated union rather than an `Error` because every case calls for a\n * different response: a v1 file can be converted, a file from a newer build can\n * be reported by version, and invalid records can name what was wrong. Each\n * variant carries only what its own case needs.\n */\nexport type TldrawFileParseError =\n | { type: \"notATldrawFile\"; cause: unknown }\n | { type: \"v1File\"; data: unknown }\n | { type: \"invalidRecords\"; cause: unknown }\n | { type: \"migrationFailed\"; reason: string }\n | { type: \"fileFormatVersionTooNew\"; version: number }\n\n/** Either the records a file held, or why it could not be read. */\nexport type ParseTldrawJsonFileResult =\n | { ok: true; value: { schema: TldrawFile[\"schema\"]; records: TldrawFile[\"records\"] } }\n | { ok: false; error: TldrawFileParseError }\n\n/**\n * Parse `.tldr` JSON text without loading it into an editor.\n *\n * The step before {@link loadMocanvasFile} for anything that wants to inspect a\n * file first — a document picker showing a thumbnail, a migration script, a\n * server validating an upload. `schema` is accepted so a caller can say which\n * schema the records should be read against; it is not consulted for a file\n * that carries its own, which every file written since the format gained an\n * envelope does.\n */\nexport function parseTldrawJsonFile({ json, schema }: { json: string; schema?: unknown }): ParseTldrawJsonFileResult {\n void schema\n const parsed = parseTldrFile(json)\n if (parsed.ok) return { ok: true, value: { schema: parsed.schema, records: parsed.records } }\n switch (parsed.error) {\n case \"v1File\":\n return { ok: false, error: { type: \"v1File\", data: parsed.cause ?? null } }\n case \"invalidRecords\":\n return { ok: false, error: { type: \"invalidRecords\", cause: parsed.cause ?? null } }\n case \"futureVersion\":\n return { ok: false, error: { type: \"fileFormatVersionTooNew\", version: Number.NaN } }\n default:\n return { ok: false, error: { type: \"notATldrawFile\", cause: parsed.cause ?? null } }\n }\n}\n\n/**\n * The editor's document as `.tldr` JSON text.\n *\n * Asynchronous by contract even though nothing here awaits: an app that\n * resolves assets to data URLs before saving needs the same signature, and\n * changing a synchronous function to an asynchronous one later would break\n * every call site.\n */\nexport async function serializeTldrawJson(editor: Editor): Promise<string> {\n return serializeMocanvasFile(editor)\n}\n\n/** The same document as a `Blob`, ready to hand to a downloader or an upload. */\nexport async function serializeTldrawJsonBlob(editor: Editor): Promise<Blob> {\n return new Blob([await serializeTldrawJson(editor)], { type: \"application/json\" })\n}\n"]}