ducjs 2.2.2 → 2.3.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.
Files changed (35) hide show
  1. package/dist/flatbuffers/duc/delta.d.ts +6 -4
  2. package/dist/flatbuffers/duc/delta.js +22 -11
  3. package/dist/flatbuffers/duc/document-grid-align-items.d.ts +5 -0
  4. package/dist/flatbuffers/duc/document-grid-align-items.js +8 -0
  5. package/dist/flatbuffers/duc/document-grid-config.d.ts +22 -0
  6. package/dist/flatbuffers/duc/document-grid-config.js +73 -0
  7. package/dist/flatbuffers/duc/duc-block-metadata.d.ts +5 -2
  8. package/dist/flatbuffers/duc/duc-block-metadata.js +23 -5
  9. package/dist/flatbuffers/duc/duc-doc-element.d.ts +6 -0
  10. package/dist/flatbuffers/duc/duc-doc-element.js +16 -1
  11. package/dist/flatbuffers/duc/duc-element-base.d.ts +6 -3
  12. package/dist/flatbuffers/duc/duc-element-base.js +26 -8
  13. package/dist/flatbuffers/duc/duc-model-element.d.ts +26 -0
  14. package/dist/flatbuffers/duc/duc-model-element.js +79 -0
  15. package/dist/flatbuffers/duc/duc-pdf-element.d.ts +3 -1
  16. package/dist/flatbuffers/duc/duc-pdf-element.js +9 -7
  17. package/dist/flatbuffers/duc/element.d.ts +5 -3
  18. package/dist/flatbuffers/duc/element.js +4 -0
  19. package/dist/flatbuffers/duc.d.ts +3 -0
  20. package/dist/flatbuffers/duc.js +3 -0
  21. package/dist/parse.d.ts +3 -2
  22. package/dist/parse.js +75 -44
  23. package/dist/restore/restoreDataState.d.ts +1 -6
  24. package/dist/restore/restoreDataState.js +9 -18
  25. package/dist/restore/restoreElements.js +39 -25
  26. package/dist/serialize.js +67 -48
  27. package/dist/types/elements/index.d.ts +34 -31
  28. package/dist/types/elements/typeChecks.js +1 -1
  29. package/dist/types/index.d.ts +5 -4
  30. package/dist/types/index.js +1 -1
  31. package/dist/utils/elements/newElement.d.ts +2 -2
  32. package/dist/utils/elements/newElement.js +4 -4
  33. package/dist/utils/index.d.ts +1 -0
  34. package/dist/utils/index.js +5 -0
  35. package/package.json +6 -5
package/dist/serialize.js CHANGED
@@ -18,6 +18,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
18
18
  */
19
19
  import * as flatbuffers from "flatbuffers";
20
20
  import * as Duc from "./flatbuffers/duc";
21
+ import { zlibSync, strToU8 } from "fflate";
21
22
  import { restore } from "./restore";
22
23
  import { encodeFunctionString, EXPORT_DATA_TYPES } from "./utils";
23
24
  /**
@@ -377,7 +378,7 @@ function writeElementBase(b, e, usv) {
377
378
  const frameId = str(b, (_j = e.frameId) !== null && _j !== void 0 ? _j : undefined);
378
379
  const bound = ((_k = e.boundElements) === null || _k === void 0 ? void 0 : _k.length) ? Duc._DucElementBase.createBoundElementsVector(b, e.boundElements.map((x) => writeBoundElement(b, x, usv))) : undefined;
379
380
  const link = str(b, (_l = e.link) !== null && _l !== void 0 ? _l : undefined);
380
- const custom = e.customData != null ? str(b, JSON.stringify(e.customData)) : undefined;
381
+ const custom = e.customData != null ? Duc._DucElementBase.createCustomDataVector(b, zlibSync(strToU8(JSON.stringify(e.customData)))) : undefined;
381
382
  Duc._DucElementBase.start_DucElementBase(b);
382
383
  if (id)
383
384
  Duc._DucElementBase.addId(b, id);
@@ -739,6 +740,24 @@ function writeColumnLayout(b, c, usv) {
739
740
  Duc.ColumnLayout.addAutoHeight(b, c.autoHeight);
740
741
  return Duc.ColumnLayout.endColumnLayout(b);
741
742
  }
743
+ function writeDocumentGridConfig(b, config, usv) {
744
+ Duc.DocumentGridConfig.startDocumentGridConfig(b);
745
+ Duc.DocumentGridConfig.addColumns(b, config.columns);
746
+ Duc.DocumentGridConfig.addGapX(b, config.gapX);
747
+ Duc.DocumentGridConfig.addGapY(b, config.gapY);
748
+ const alignItems = (() => {
749
+ if (config.alignItems === 'start')
750
+ return Duc.DOCUMENT_GRID_ALIGN_ITEMS.START;
751
+ if (config.alignItems === 'center')
752
+ return Duc.DOCUMENT_GRID_ALIGN_ITEMS.CENTER;
753
+ if (config.alignItems === 'end')
754
+ return Duc.DOCUMENT_GRID_ALIGN_ITEMS.END;
755
+ return Duc.DOCUMENT_GRID_ALIGN_ITEMS.START;
756
+ })();
757
+ Duc.DocumentGridConfig.addAlignItems(b, alignItems);
758
+ Duc.DocumentGridConfig.addFirstPageAlone(b, config.firstPageAlone);
759
+ return Duc.DocumentGridConfig.endDocumentGridConfig(b);
760
+ }
742
761
  function writeText(b, e, usv) {
743
762
  var _a;
744
763
  const base = writeElementBase(b, e, usv);
@@ -776,7 +795,7 @@ function writeBlockAttrDef(b, d, usv) {
776
795
  }
777
796
  function writeBlockMetadata(b, metadata) {
778
797
  const source = b.createString(metadata.source);
779
- const localization = metadata.localization ? b.createString(JSON.stringify(metadata.localization)) : undefined;
798
+ const localization = metadata.localization ? Duc.DucBlockMetadata.createLocalizationVector(b, zlibSync(strToU8(JSON.stringify(metadata.localization)))) : undefined;
780
799
  Duc.DucBlockMetadata.startDucBlockMetadata(b);
781
800
  Duc.DucBlockMetadata.addSource(b, source);
782
801
  Duc.DucBlockMetadata.addUsageCount(b, metadata.usageCount);
@@ -835,8 +854,14 @@ function writeBlockInstance(b, i, usv) {
835
854
  Duc.DucBlockDuplicationArray.startDucBlockDuplicationArray(b);
836
855
  Duc.DucBlockDuplicationArray.addRows(b, i.duplicationArray.rows);
837
856
  Duc.DucBlockDuplicationArray.addCols(b, i.duplicationArray.cols);
838
- Duc.DucBlockDuplicationArray.addRowSpacing(b, getPrecisionValue(i.duplicationArray.rowSpacing, usv));
839
- Duc.DucBlockDuplicationArray.addColSpacing(b, getPrecisionValue(i.duplicationArray.colSpacing, usv));
857
+ const rSpacing = typeof i.duplicationArray.rowSpacing === 'number'
858
+ ? i.duplicationArray.rowSpacing
859
+ : getPrecisionValue(i.duplicationArray.rowSpacing, usv);
860
+ const cSpacing = typeof i.duplicationArray.colSpacing === 'number'
861
+ ? i.duplicationArray.colSpacing
862
+ : getPrecisionValue(i.duplicationArray.colSpacing, usv);
863
+ Duc.DucBlockDuplicationArray.addRowSpacing(b, rSpacing);
864
+ Duc.DucBlockDuplicationArray.addColSpacing(b, cSpacing);
840
865
  return Duc.DucBlockDuplicationArray.endDucBlockDuplicationArray(b);
841
866
  })()
842
867
  : undefined;
@@ -870,9 +895,9 @@ function writeBlockCollection(b, c) {
870
895
  const metadata = c.metadata;
871
896
  let localizationOffset;
872
897
  if (metadata.localization) {
873
- // localization is stored as a JSON string
874
- const localizationStr = JSON.stringify(metadata.localization);
875
- localizationOffset = b.createString(localizationStr);
898
+ // localization is stored as compressed binary JSON data
899
+ const localizationBin = zlibSync(strToU8(JSON.stringify(metadata.localization)));
900
+ localizationOffset = Duc.DucBlockMetadata.createLocalizationVector(b, localizationBin);
876
901
  }
877
902
  const source = b.createString(metadata.source);
878
903
  Duc.DucBlockMetadata.startDucBlockMetadata(b);
@@ -1377,6 +1402,8 @@ function writeDoc(b, e, usv) {
1377
1402
  Duc.ColumnLayout.addAutoHeight(b, col.autoHeight);
1378
1403
  return Duc.ColumnLayout.endColumnLayout(b);
1379
1404
  })();
1405
+ const fileId = e.fileId ? b.createString(e.fileId) : undefined;
1406
+ const gridConfig = writeDocumentGridConfig(b, e.gridConfig, usv);
1380
1407
  Duc.DucDocElement.startDucDocElement(b);
1381
1408
  Duc.DucDocElement.addBase(b, base);
1382
1409
  Duc.DucDocElement.addStyle(b, style);
@@ -1385,36 +1412,23 @@ function writeDoc(b, e, usv) {
1385
1412
  Duc.DucDocElement.addFlowDirection(b, e.flowDirection);
1386
1413
  Duc.DucDocElement.addColumns(b, columns);
1387
1414
  Duc.DucDocElement.addAutoResize(b, e.autoResize);
1415
+ if (fileId)
1416
+ Duc.DucDocElement.addFileId(b, fileId);
1417
+ Duc.DucDocElement.addGridConfig(b, gridConfig);
1388
1418
  return Duc.DucDocElement.endDucDocElement(b);
1389
1419
  }
1390
1420
  /**
1391
- * Parametric, PDF, Mermaid, Embeddable
1421
+ * PDF, Mermaid, Embeddable
1392
1422
  */
1393
- function writeParametricSource(b, s, usv) {
1394
- Duc.ParametricSource.startParametricSource(b);
1395
- Duc.ParametricSource.addType(b, s.type);
1396
- if (s.type === Duc.PARAMETRIC_SOURCE_TYPE.CODE) {
1397
- Duc.ParametricSource.addCode(b, b.createString(s.code));
1398
- }
1399
- else {
1400
- Duc.ParametricSource.addFileId(b, b.createString(s.fileId));
1401
- }
1402
- return Duc.ParametricSource.endParametricSource(b);
1403
- }
1404
- function writeParametric(b, e, usv) {
1405
- const base = writeElementBase(b, e, usv);
1406
- const src = writeParametricSource(b, e.source, usv);
1407
- Duc.DucParametricElement.startDucParametricElement(b);
1408
- Duc.DucParametricElement.addBase(b, base);
1409
- Duc.DucParametricElement.addSource(b, src);
1410
- return Duc.DucParametricElement.endDucParametricElement(b);
1411
- }
1412
1423
  function writePdf(b, e, usv) {
1413
1424
  const base = writeElementBase(b, e, usv);
1414
- const fileId = b.createString(e.fileId);
1425
+ const fileId = e.fileId ? b.createString(e.fileId) : undefined;
1426
+ const gridConfig = writeDocumentGridConfig(b, e.gridConfig, usv);
1415
1427
  Duc.DucPdfElement.startDucPdfElement(b);
1416
1428
  Duc.DucPdfElement.addBase(b, base);
1417
- Duc.DucPdfElement.addFileId(b, fileId);
1429
+ if (fileId)
1430
+ Duc.DucPdfElement.addFileId(b, fileId);
1431
+ Duc.DucPdfElement.addGridConfig(b, gridConfig);
1418
1432
  return Duc.DucPdfElement.endDucPdfElement(b);
1419
1433
  }
1420
1434
  function writeMermaid(b, e, usv) {
@@ -1431,6 +1445,21 @@ function writeMermaid(b, e, usv) {
1431
1445
  Duc.DucMermaidElement.addSvgPath(b, svg);
1432
1446
  return Duc.DucMermaidElement.endDucMermaidElement(b);
1433
1447
  }
1448
+ function writeModel(b, e, usv) {
1449
+ var _a;
1450
+ const base = writeElementBase(b, e, usv);
1451
+ const src = b.createString(e.source);
1452
+ const svg = e.svgPath ? b.createString(e.svgPath) : undefined;
1453
+ const fileIds = ((_a = e.fileIds) === null || _a === void 0 ? void 0 : _a.length) ? Duc.DucModelElement.createFileIdsVector(b, e.fileIds.map((id) => b.createString(id))) : undefined;
1454
+ Duc.DucModelElement.startDucModelElement(b);
1455
+ Duc.DucModelElement.addBase(b, base);
1456
+ Duc.DucModelElement.addSource(b, src);
1457
+ if (svg)
1458
+ Duc.DucModelElement.addSvgPath(b, svg);
1459
+ if (fileIds)
1460
+ Duc.DucModelElement.addFileIds(b, fileIds);
1461
+ return Duc.DucModelElement.endDucModelElement(b);
1462
+ }
1434
1463
  function writeEmbeddable(b, e, usv) {
1435
1464
  const base = writeElementBase(b, e, usv);
1436
1465
  Duc.DucEmbeddableElement.startDucEmbeddableElement(b);
@@ -1632,9 +1661,9 @@ function writeElementWrapper(b, e, usv) {
1632
1661
  type = Duc.Element.DucDocElement;
1633
1662
  elem = writeDoc(b, e, usv);
1634
1663
  break;
1635
- case "parametric":
1636
- type = Duc.Element.DucParametricElement;
1637
- elem = writeParametric(b, e, usv);
1664
+ case "model":
1665
+ type = Duc.Element.DucModelElement;
1666
+ elem = writeModel(b, e, usv);
1638
1667
  break;
1639
1668
  case "embeddable":
1640
1669
  type = Duc.Element.DucEmbeddableElement;
@@ -2228,28 +2257,18 @@ function serializeCheckpoint(b, c) {
2228
2257
  return Duc.Checkpoint.endCheckpoint(b);
2229
2258
  }
2230
2259
  function writeJsonPatch(b, p) {
2231
- const ops = p.map((op) => {
2232
- const opStr = b.createString(op.op);
2233
- const pathStr = b.createString(op.path);
2234
- const fromStr = op.from !== undefined ? b.createString(op.from) : undefined;
2235
- const valueStr = op.value !== undefined ? b.createString(JSON.stringify(op.value)) : undefined;
2236
- Duc.JSONPatchOperation.startJSONPatchOperation(b);
2237
- Duc.JSONPatchOperation.addOp(b, opStr);
2238
- Duc.JSONPatchOperation.addPath(b, pathStr);
2239
- if (fromStr)
2240
- Duc.JSONPatchOperation.addFrom(b, fromStr);
2241
- if (valueStr)
2242
- Duc.JSONPatchOperation.addValue(b, valueStr);
2243
- return Duc.JSONPatchOperation.endJSONPatchOperation(b);
2244
- });
2245
- return Duc.Delta.createPatchVector(b, ops);
2260
+ // Compress the JSON patch data
2261
+ const patchData = zlibSync(strToU8(JSON.stringify(p)));
2262
+ const offset = Duc.Delta.createPatchVector(b, patchData);
2263
+ return { offset, sizeBytes: patchData.length };
2246
2264
  }
2247
2265
  function serializeDelta(b, d) {
2248
2266
  const base = serializeVersionBase(b, d);
2249
- const patch = writeJsonPatch(b, d.patch);
2267
+ const { offset: patch, sizeBytes } = writeJsonPatch(b, d.patch);
2250
2268
  Duc.Delta.startDelta(b);
2251
2269
  Duc.Delta.addBase(b, base);
2252
2270
  Duc.Delta.addPatch(b, patch);
2271
+ Duc.Delta.addSizeBytes(b, BigInt(sizeBytes));
2253
2272
  return Duc.Delta.endDelta(b);
2254
2273
  }
2255
2274
  function serializeDucVersionGraph(b, vg) {
@@ -1,6 +1,6 @@
1
1
  export * from "./typeChecks";
2
2
  import { DucView, PrecisionValue, Scope } from "..";
3
- import { BEZIER_MIRRORING, BLENDING, BLOCK_ATTACHMENT, BOOLEAN_OPERATION, COLUMN_TYPE, DATUM_BRACKET_STYLE, DATUM_TARGET_TYPE, DIMENSION_FIT_RULE, DIMENSION_TEXT_PLACEMENT, DIMENSION_TYPE, ELEMENT_CONTENT_PREFERENCE, FEATURE_MODIFIER, GDT_SYMBOL, HATCH_STYLE, IMAGE_STATUS, LINE_HEAD, LINE_SPACING_TYPE, MARK_ELLIPSE_CENTER, MATERIAL_CONDITION, PARAMETRIC_SOURCE_TYPE, STACKED_TEXT_ALIGN, STROKE_CAP, STROKE_JOIN, STROKE_PLACEMENT, STROKE_PREFERENCE, STROKE_SIDE_PREFERENCE, TABLE_CELL_ALIGNMENT, TABLE_FLOW_DIRECTION, TEXT_ALIGN, TEXT_FIELD_SOURCE_PROPERTY, TEXT_FIELD_SOURCE_TYPE, TEXT_FLOW_DIRECTION, TOLERANCE_DISPLAY, TOLERANCE_TYPE, TOLERANCE_ZONE_TYPE, VERTICAL_ALIGN, VIEWPORT_SHADE_PLOT } from "../../flatbuffers/duc";
3
+ import { BEZIER_MIRRORING, BLENDING, BLOCK_ATTACHMENT, BOOLEAN_OPERATION, COLUMN_TYPE, DATUM_BRACKET_STYLE, DATUM_TARGET_TYPE, DIMENSION_FIT_RULE, DIMENSION_TEXT_PLACEMENT, DIMENSION_TYPE, ELEMENT_CONTENT_PREFERENCE, FEATURE_MODIFIER, GDT_SYMBOL, HATCH_STYLE, IMAGE_STATUS, LINE_HEAD, LINE_SPACING_TYPE, MARK_ELLIPSE_CENTER, MATERIAL_CONDITION, STACKED_TEXT_ALIGN, STROKE_CAP, STROKE_JOIN, STROKE_PLACEMENT, STROKE_PREFERENCE, STROKE_SIDE_PREFERENCE, TABLE_CELL_ALIGNMENT, TABLE_FLOW_DIRECTION, TEXT_ALIGN, TEXT_FIELD_SOURCE_PROPERTY, TEXT_FIELD_SOURCE_TYPE, TEXT_FLOW_DIRECTION, TOLERANCE_DISPLAY, TOLERANCE_TYPE, TOLERANCE_ZONE_TYPE, VERTICAL_ALIGN, VIEWPORT_SHADE_PLOT } from "../../flatbuffers/duc";
4
4
  import { Standard, StandardUnits } from "../../technical/standards";
5
5
  import { FONT_FAMILY, FREEDRAW_EASINGS } from "../../utils/constants";
6
6
  import { Axis, GeometricPoint, Percentage, Radian, ScaleFactor } from "../geometryTypes";
@@ -134,7 +134,7 @@ export type DucGenericElement = DucSelectionElement | DucRectangleElement;
134
134
  * no computed data. The list of all DucElements should be shareable
135
135
  * between peers and contain no state local to the peer.
136
136
  */
137
- export type DucElement = DucGenericElement | DucTextElement | DucLinearElement | DucFreeDrawElement | DucArrowElement | DucImageElement | DucFrameElement | DucEmbeddableElement | DucTableElement | DucDocElement | DucEllipseElement | DucPolygonElement | DucParametricElement | DucFeatureControlFrameElement | DucLeaderElement | DucDimensionElement | DucViewportElement | DucPlotElement | DucXRayElement | DucPdfElement | DucMermaidElement;
137
+ export type DucElement = DucGenericElement | DucTextElement | DucLinearElement | DucFreeDrawElement | DucArrowElement | DucImageElement | DucFrameElement | DucEmbeddableElement | DucTableElement | DucDocElement | DucEllipseElement | DucPolygonElement | DucModelElement | DucFeatureControlFrameElement | DucLeaderElement | DucDimensionElement | DucViewportElement | DucPlotElement | DucXRayElement | DucPdfElement | DucMermaidElement;
138
138
  export type DucElementTypes = DucElement["type"];
139
139
  export type NonDeleted<TElement extends DucElement> = TElement & {
140
140
  isDeleted: boolean;
@@ -316,9 +316,21 @@ export type DucEllipseElement = _DucElementBase & {
316
316
  export type DucEmbeddableElement = _DucElementBase & {
317
317
  type: "embeddable";
318
318
  };
319
+ /**
320
+ * Configuration for PDF grid layout
321
+ */
322
+ export type DocumentGridConfig = {
323
+ columns: number;
324
+ gapX: number;
325
+ gapY: number;
326
+ alignItems: 'start' | 'center' | 'end';
327
+ firstPageAlone: boolean;
328
+ };
319
329
  export type DucPdfElement = _DucElementBase & {
320
330
  type: "pdf";
321
331
  fileId: ExternalFileId | null;
332
+ /** Configuration for rendering the document in a grid layout */
333
+ gridConfig: DocumentGridConfig;
322
334
  };
323
335
  export type DucMermaidElement = _DucElementBase & {
324
336
  type: "mermaid";
@@ -746,8 +758,10 @@ export type DucBlockAttributeDefinition = {
746
758
  /** If true, the attribute's value is fixed and cannot be changed after insertion. */
747
759
  isConstant: boolean;
748
760
  };
749
- /** Indicates whether the block belongs to the project, organization or community */
750
- export type BlockSourceType = string | "organization" | "community";
761
+ /**
762
+ * Indicates the source drawing of a block.
763
+ */
764
+ export type BlockSource = string;
751
765
  export interface BlockLocalizationEntry {
752
766
  title: string;
753
767
  description?: string;
@@ -758,8 +772,8 @@ export interface BlockLocalizationEntry {
758
772
  */
759
773
  export type BlockLocalizationMap = Record<string, BlockLocalizationEntry>;
760
774
  export interface DucBlockMetadata {
761
- /** Indicates whether the block belongs to the project, organization or community */
762
- source: BlockSourceType;
775
+ /** Drawing id this block originates from */
776
+ source?: BlockSource;
763
777
  /** Total number of times the block was instantiated */
764
778
  usageCount: number;
765
779
  /** Creation timestamp */
@@ -1355,10 +1369,8 @@ export type TextColumn = {
1355
1369
  export type DucDocElement = _DucElementBase & DucDocStyle & {
1356
1370
  type: "doc";
1357
1371
  /**
1358
- * The content of the document, stored as a Markdown string.
1359
- * This approach allows a rich text editor (like Tiptap) to manage the complex
1360
- * inline formatting (bold, italic, colors, hyperlinks, etc.) while keeping the
1361
- * core data structure simple and clean.
1372
+ * The content of the document, stored as a code string.
1373
+ * This approach allows to use a rich text editor that can compile to PDF using Typst code
1362
1374
  *
1363
1375
  * It can also contain wildcards like `{@fieldname}` for dynamic data insertion.
1364
1376
  * Example: "This is **bold text** and this is a {color:red}red word{/color}."
@@ -1367,6 +1379,9 @@ export type DucDocElement = _DucElementBase & DucDocStyle & {
1367
1379
  * Example: "This document was last saved on {{SaveDate}} by {{Author}}."
1368
1380
  */
1369
1381
  text: string;
1382
+ fileId: ExternalFileId | null;
1383
+ /** Configuration for rendering the document in a grid layout */
1384
+ gridConfig: DocumentGridConfig;
1370
1385
  /**
1371
1386
  * An array of metadata objects that define the behavior of the placeholders
1372
1387
  * found in the `text` property. If this is empty, the text is treated
@@ -1399,27 +1414,15 @@ export type DucDocElement = _DucElementBase & DucDocStyle & {
1399
1414
  autoResize: boolean;
1400
1415
  };
1401
1416
  /**
1402
- * Defines the source of the 3D geometry for a Parametric Element.
1403
- * The geometry is either generated from live code or loaded from an external file.
1404
- */
1405
- export type ParametricElementSource = {
1406
- /** The geometry is defined by executable Replicad code. */
1407
- type: PARAMETRIC_SOURCE_TYPE.CODE;
1408
- /** The JavaScript code that generates the Replicad model. */
1409
- code: string;
1410
- } | {
1411
- /** The geometry is loaded from a static 3D file. */
1412
- type: PARAMETRIC_SOURCE_TYPE.FILE;
1413
- /** A reference to the imported file in the DucExternalFiles collection. */
1414
- fileId: ExternalFileId;
1415
- };
1416
- /**
1417
- * An element that embeds a 3D model on the 2D canvas, defined either by
1418
- * parametric Replicad code or by an imported 3D file (e.g., STEP, STL).
1417
+ * An element that embeds a 3D model on the 2D canvas, defined by build123d python code.
1419
1418
  * It includes its own 3D view and display controls.
1420
1419
  */
1421
- export type DucParametricElement = _DucElementBase & {
1422
- type: "parametric";
1423
- /** Defines the source of the 3D geometry (either from code or a file). */
1424
- source: ParametricElementSource;
1420
+ export type DucModelElement = _DucElementBase & {
1421
+ type: "model";
1422
+ /** Defines the source of the model using build123d python code */
1423
+ source: string;
1424
+ /** The last known SVG path representation of the 3D model for quick rendering on the canvas */
1425
+ svgPath: string | null;
1426
+ /** Possibly connected external files, such as STEP, STL or other reference models */
1427
+ fileIds: ExternalFileId[];
1425
1428
  };
@@ -133,7 +133,7 @@ export const isDucElement = (element) => {
133
133
  case "leader":
134
134
  case "doc":
135
135
  case "selection":
136
- case "parametric":
136
+ case "model":
137
137
  case "featurecontrolframe":
138
138
  case "viewport":
139
139
  case "plot":
@@ -1,14 +1,14 @@
1
1
  export * from "./elements";
2
2
  export * from "./geometryTypes";
3
- export * from "./utility-types";
4
3
  export * from "./typeChecks";
4
+ export * from "./utility-types";
5
5
  import { OBJECT_SNAP_MODE, PRUNING_LEVEL } from "../flatbuffers/duc";
6
6
  import { SupportedMeasures } from "../technical/scopes";
7
7
  import { Standard } from "../technical/standards";
8
+ import type { GRID_DISPLAY_TYPE, GRID_TYPE, SNAP_MARKER_SHAPE, SNAP_MODE, SNAP_OVERRIDE_BEHAVIOR } from "../utils/constants";
8
9
  import { DucBindableElement, DucBlock, DucBlockCollection, DucBlockInstance, DucElement, DucElementType, DucGroup, DucIframeLikeElement, DucLayer, DucLinearElement, DucPoint, DucRegion, DucTextElement, ElementBackground, ElementStroke, ExternalFileId, FontFamilyValues, LineHead, NonDeleted, TextAlign } from "./elements";
9
10
  import { GeometricPoint, Percentage, Radian, ScaleFactor } from "./geometryTypes";
10
- import { MakeBrand, MaybePromise, ValueOf } from "./utility-types";
11
- import type { GRID_DISPLAY_TYPE, GRID_TYPE, SNAP_MARKER_SHAPE, SNAP_MODE, SNAP_OVERRIDE_BEHAVIOR } from "../utils/constants";
11
+ import { MakeBrand, MarkOptional, MaybePromise, ValueOf } from "./utility-types";
12
12
  /**
13
13
  * Root data structure for the stored data state
14
14
  */
@@ -37,6 +37,7 @@ export interface ExportedDataState {
37
37
  id: string | undefined;
38
38
  }
39
39
  export type ExportedDataStateContent = Omit<ExportedDataState, "type" | "version" | "source">;
40
+ export type BaseExportedDataState = MarkOptional<ExportedDataStateContent, "elements" | "localState" | "versionGraph">;
40
41
  /**
41
42
  * A version of the data state where all fields are optional.
42
43
  * This is useful for importing data where some fields might be missing.
@@ -111,7 +112,7 @@ export type SuggestedPointBinding = [
111
112
  "start" | "end" | "both",
112
113
  NonDeleted<DucBindableElement>
113
114
  ];
114
- export type ToolType = "selection" | "rectangle" | "polygon" | "ellipse" | "line" | "freedraw" | "text" | "image" | "eraser" | "hand" | "frame" | "plot" | "embeddable" | "ruler" | "lasso" | "laser" | "table";
115
+ export type ToolType = "selection" | "rectangle" | "polygon" | "ellipse" | "line" | "freedraw" | "text" | "image" | "eraser" | "hand" | "frame" | "plot" | "embeddable" | "ruler" | "lasso" | "laser" | "table" | "doc" | "pdf";
115
116
  export type ElementOrToolType = DucElementType | ToolType | "custom";
116
117
  /**
117
118
  * Defines the global, persistent settings for the drawing. These are fundamental
@@ -1,4 +1,4 @@
1
1
  export * from "./elements";
2
2
  export * from "./geometryTypes";
3
- export * from "./utility-types";
4
3
  export * from "./typeChecks";
4
+ export * from "./utility-types";
@@ -1,5 +1,5 @@
1
1
  import { Scope } from "../../types";
2
- import { DucArrowElement, DucDimensionElement, DucDocElement, DucElement, DucEllipseElement, DucEmbeddableElement, DucFeatureControlFrameElement, DucFrameElement, DucFreeDrawElement, DucGenericElement, DucImageElement, DucLeaderElement, DucLinearElement, DucMermaidElement, DucParametricElement, DucPdfElement, DucPlotElement, DucPolygonElement, DucTableElement, DucTextElement, DucViewportElement, DucXRayElement, ElementConstructorOpts, ElementUpdate, NonDeleted } from "../../types/elements";
2
+ import { DucArrowElement, DucDimensionElement, DucDocElement, DucElement, DucEllipseElement, DucEmbeddableElement, DucFeatureControlFrameElement, DucFrameElement, DucFreeDrawElement, DucGenericElement, DucImageElement, DucLeaderElement, DucLinearElement, DucMermaidElement, DucModelElement, DucPdfElement, DucPlotElement, DucPolygonElement, DucTableElement, DucTextElement, DucViewportElement, DucXRayElement, ElementConstructorOpts, ElementUpdate, NonDeleted } from "../../types/elements";
3
3
  import { Mutable } from "../../types/utility-types";
4
4
  export declare const newElementWith: <TElement extends DucElement>(element: TElement, updates: ElementUpdate<TElement>,
5
5
  /** pass `true` to always regenerate */
@@ -46,7 +46,7 @@ export declare const newXRayElement: (currentScope: Scope, opts: ElementConstruc
46
46
  export declare const newLeaderElement: (currentScope: Scope, opts: Partial<DucLeaderElement> & ElementConstructorOpts) => NonDeleted<DucLeaderElement>;
47
47
  export declare const newDimensionElement: (currentScope: Scope, opts: ElementConstructorOpts) => NonDeleted<DucDimensionElement>;
48
48
  export declare const newFeatureControlFrameElement: (currentScope: Scope, opts: ElementConstructorOpts) => NonDeleted<DucFeatureControlFrameElement>;
49
- export declare const newParametricElement: (currentScope: Scope, opts: ElementConstructorOpts) => NonDeleted<DucParametricElement>;
49
+ export declare const newParametricElement: (currentScope: Scope, opts: ElementConstructorOpts) => NonDeleted<DucModelElement>;
50
50
  /**
51
51
  * Clones DucElement data structure. Does not regenerate id, nonce, or
52
52
  * any value. The purpose is to to break object references for immutability
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { getUpdatedTimestamp, getZoom } from "..";
13
- import { BLOCK_ATTACHMENT, COLUMN_TYPE, DATUM_BRACKET_STYLE, IMAGE_STATUS, LINE_SPACING_TYPE, PARAMETRIC_SOURCE_TYPE, STACKED_TEXT_ALIGN, TEXT_FLOW_DIRECTION, VERTICAL_ALIGN, VIEWPORT_SHADE_PLOT } from "../../flatbuffers/duc";
13
+ import { BLOCK_ATTACHMENT, COLUMN_TYPE, DATUM_BRACKET_STYLE, IMAGE_STATUS, LINE_SPACING_TYPE, STACKED_TEXT_ALIGN, TEXT_FLOW_DIRECTION, VERTICAL_ALIGN, VIEWPORT_SHADE_PLOT } from "../../flatbuffers/duc";
14
14
  import { getPrecisionValueFromRaw } from "../../technical/scopes";
15
15
  import { DEFAULT_ELEMENT_PROPS, DEFAULT_ELLIPSE_ELEMENT, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FREEDRAW_ELEMENT, DEFAULT_POLYGON_SIDES, DEFAULT_TEXT_ALIGN, DEFAULT_VERTICAL_ALIGN } from "../constants";
16
16
  import { randomId, randomInteger } from "../math/random";
@@ -153,11 +153,11 @@ export const newImageElement = (currentScope, opts) => {
153
153
  export const newTableElement = (currentScope, opts) => (Object.assign(Object.assign(Object.assign({}, _newElementBase("table", currentScope, opts)), getDefaultTableData(currentScope)), { type: "table" }));
154
154
  export const newDocElement = (currentScope, opts) => {
155
155
  var _a, _b, _c, _d;
156
- return (Object.assign(Object.assign({}, _newElementBase("doc", currentScope, opts)), { type: "doc", text: opts.text || "", dynamic: opts.dynamic || [], flowDirection: opts.flowDirection || TEXT_FLOW_DIRECTION.TOP_TO_BOTTOM, columns: opts.columns || { type: COLUMN_TYPE.NO_COLUMNS, definitions: [], autoHeight: true }, autoResize: (_a = opts.autoResize) !== null && _a !== void 0 ? _a : true,
156
+ return (Object.assign(Object.assign({}, _newElementBase("doc", currentScope, opts)), { type: "doc", text: opts.text || "", dynamic: opts.dynamic || [], flowDirection: opts.flowDirection || TEXT_FLOW_DIRECTION.TOP_TO_BOTTOM, columns: opts.columns || { type: COLUMN_TYPE.NO_COLUMNS, definitions: [], autoHeight: true }, autoResize: (_a = opts.autoResize) !== null && _a !== void 0 ? _a : true, fileId: null, gridConfig: { columns: 1, gapX: 0, gapY: 0, alignItems: 'start', firstPageAlone: false },
157
157
  // DucDocStyle properties
158
158
  isLtr: (_b = opts.isLtr) !== null && _b !== void 0 ? _b : true, fontFamily: opts.fontFamily || DEFAULT_FONT_FAMILY, bigFontFamily: opts.bigFontFamily || "sans-serif", textAlign: opts.textAlign || DEFAULT_TEXT_ALIGN, verticalAlign: opts.verticalAlign || DEFAULT_VERTICAL_ALIGN, lineHeight: opts.lineHeight || 1.2, lineSpacing: opts.lineSpacing || { type: LINE_SPACING_TYPE.MULTIPLE, value: 1.2 }, obliqueAngle: opts.obliqueAngle || 0, fontSize: opts.fontSize || getPrecisionValueFromRaw(DEFAULT_FONT_SIZE, currentScope, currentScope), paperTextHeight: opts.paperTextHeight, widthFactor: opts.widthFactor || 1, isUpsideDown: (_c = opts.isUpsideDown) !== null && _c !== void 0 ? _c : false, isBackwards: (_d = opts.isBackwards) !== null && _d !== void 0 ? _d : false, paragraph: opts.paragraph || { firstLineIndent: getPrecisionValueFromRaw(0, currentScope, currentScope), hangingIndent: getPrecisionValueFromRaw(0, currentScope, currentScope), leftIndent: getPrecisionValueFromRaw(0, currentScope, currentScope), rightIndent: getPrecisionValueFromRaw(0, currentScope, currentScope), spaceBefore: getPrecisionValueFromRaw(0, currentScope, currentScope), spaceAfter: getPrecisionValueFromRaw(0, currentScope, currentScope), tabStops: [] }, stackFormat: opts.stackFormat || { autoStack: false, stackChars: [], properties: { upperScale: 0.7, lowerScale: 0.7, alignment: STACKED_TEXT_ALIGN.CENTER } } }));
159
159
  };
160
- export const newPdfElement = (currentScope, opts) => (Object.assign(Object.assign({ fileId: null }, _newElementBase("pdf", currentScope, opts)), { type: "pdf" }));
160
+ export const newPdfElement = (currentScope, opts) => (Object.assign(Object.assign({ fileId: null, gridConfig: { columns: 1, gapX: 0, gapY: 0, alignItems: 'start', firstPageAlone: false } }, _newElementBase("pdf", currentScope, opts)), { type: "pdf" }));
161
161
  export const newMermaidElement = (currentScope, opts) => (Object.assign(Object.assign({ source: "", theme: undefined, svgPath: null }, _newElementBase("mermaid", currentScope, opts)), { type: "mermaid" }));
162
162
  export const newXRayElement = (currentScope, opts) => (Object.assign(Object.assign({ origin: { x: getPrecisionValueFromRaw(0, currentScope, currentScope), y: getPrecisionValueFromRaw(0, currentScope, currentScope) }, direction: { x: getPrecisionValueFromRaw(1, currentScope, currentScope), y: getPrecisionValueFromRaw(0, currentScope, currentScope) }, startFromOrigin: false, color: '#FF00FF' }, _newElementBase("xray", currentScope, opts)), { type: "xray" }));
163
163
  export const newLeaderElement = (currentScope, opts) => {
@@ -179,7 +179,7 @@ export const newFeatureControlFrameElement = (currentScope, opts) => {
179
179
  bracketStyle: DATUM_BRACKET_STYLE.SQUARE
180
180
  } }, _newElementBase("featurecontrolframe", currentScope, opts)), { type: "featurecontrolframe" });
181
181
  };
182
- export const newParametricElement = (currentScope, opts) => (Object.assign(Object.assign({ source: { type: PARAMETRIC_SOURCE_TYPE.CODE, code: "" } }, _newElementBase("parametric", currentScope, opts)), { type: 'parametric' }));
182
+ export const newParametricElement = (currentScope, opts) => (Object.assign(Object.assign({ source: "", svgPath: null, fileIds: [] }, _newElementBase("model", currentScope, opts)), { type: 'model' }));
183
183
  // Simplified deep clone for the purpose of cloning DucElement.
184
184
  //
185
185
  // Only clones plain objects and arrays. Doesn't clone Date, RegExp, Map, Set,
@@ -24,6 +24,7 @@ export declare const isFiniteNumber: (value: any) => value is number;
24
24
  export declare const arrayToMap: <T extends {
25
25
  id: string;
26
26
  } | string>(items: readonly T[] | Map<string, T>) => Map<any, any>;
27
+ export declare function omitKeys<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
27
28
  /**
28
29
  * Checks whether first directional character is RTL. Meaning whether it starts
29
30
  * with RTL characters, or indeterminate (numbers etc.) characters followed by
@@ -41,6 +41,11 @@ export const arrayToMap = (items) => {
41
41
  return acc;
42
42
  }, new Map());
43
43
  };
44
+ export function omitKeys(obj, keys) {
45
+ const result = Object.assign({}, obj);
46
+ keys.forEach(key => delete result[key]);
47
+ return result;
48
+ }
44
49
  const RS_LTR_CHARS = "A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF" +
45
50
  "\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF";
46
51
  const RS_RTL_CHARS = "\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ducjs",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "The duc 2D CAD file format is a cornerstone of our advanced design system, conceived to cater to professionals seeking precision and efficiency in their design work.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -43,12 +43,13 @@
43
43
  "undici-types": "^6.21.0"
44
44
  },
45
45
  "dependencies": {
46
- "flatbuffers": "^24.12.23",
47
- "nanoid": "5.1.5",
48
- "tinycolor2": "1.6.0",
49
46
  "@braintree/sanitize-url": "6.0.2",
50
47
  "browser-fs-access": "0.35.0",
51
- "perfect-freehand": "1.2.2"
48
+ "fflate": "^0.8.2",
49
+ "flatbuffers": "^24.12.23",
50
+ "nanoid": "5.1.5",
51
+ "perfect-freehand": "1.2.2",
52
+ "tinycolor2": "1.6.0"
52
53
  },
53
54
  "files": [
54
55
  "dist",