ducjs 3.2.2 → 3.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.
Binary file
@@ -944,9 +944,20 @@ export const isValidUint8Array = (value) => {
944
944
  if (value instanceof Uint8Array) {
945
945
  return value.byteLength > 0 ? value : undefined;
946
946
  }
947
+ if (ArrayBuffer.isView(value)) {
948
+ const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
949
+ return bytes.byteLength > 0 ? bytes : undefined;
950
+ }
947
951
  if (value instanceof ArrayBuffer) {
948
952
  return value.byteLength > 0 ? new Uint8Array(value) : undefined;
949
953
  }
954
+ if (Array.isArray(value)) {
955
+ if (value.length === 0 || !value.every((entry) => typeof entry === "number")) {
956
+ return undefined;
957
+ }
958
+ const bytes = new Uint8Array(value);
959
+ return bytes.byteLength > 0 ? bytes : undefined;
960
+ }
950
961
  if (typeof value === "string") {
951
962
  let base64String = value;
952
963
  if (value.startsWith("data:")) {
@@ -976,6 +987,13 @@ export const isValidUint8Array = (value) => {
976
987
  return undefined;
977
988
  }
978
989
  }
990
+ if (value && typeof value === "object") {
991
+ const entries = Object.values(value);
992
+ if (entries.length > 0 && entries.every((entry) => typeof entry === "number")) {
993
+ const bytes = new Uint8Array(entries);
994
+ return bytes.byteLength > 0 ? bytes : undefined;
995
+ }
996
+ }
979
997
  return undefined;
980
998
  };
981
999
  /**
package/dist/serialize.js CHANGED
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { restore } from "./restore";
10
+ import { isValidUint8Array, restore } from "./restore";
11
11
  import { transformToRust } from "./transform";
12
12
  import { ensureWasm, wasmGetCurrentSchemaVersion, wasmSerializeDuc } from "./wasm";
13
13
  const getSchemaVersionFromEnv = () => {
@@ -111,28 +111,24 @@ function prepareVersionGraphForSerialization(vg) {
111
111
  if (!vg || typeof vg !== "object")
112
112
  return undefined;
113
113
  const checkpoints = Array.isArray(vg.checkpoints)
114
- ? vg.checkpoints.filter((cp) => {
115
- const data = cp === null || cp === void 0 ? void 0 : cp.data;
116
- if (data instanceof Uint8Array)
117
- return data.byteLength > 0;
118
- if (data instanceof ArrayBuffer)
119
- return data.byteLength > 0;
120
- // Accept base64 strings (from JSON imports)
121
- if (typeof data === "string" && data.length > 0)
122
- return true;
123
- return false;
114
+ ? vg.checkpoints.flatMap((checkpoint) => {
115
+ const data = isValidUint8Array(checkpoint === null || checkpoint === void 0 ? void 0 : checkpoint.data);
116
+ if (!(data === null || data === void 0 ? void 0 : data.byteLength)) {
117
+ return [];
118
+ }
119
+ return [Object.assign(Object.assign({}, checkpoint), { data })];
124
120
  })
125
121
  : [];
122
+ const validCheckpointIds = new Set(checkpoints
123
+ .map((checkpoint) => checkpoint === null || checkpoint === void 0 ? void 0 : checkpoint.id)
124
+ .filter((checkpointId) => typeof checkpointId === "string" && checkpointId.length > 0));
126
125
  const deltas = Array.isArray(vg.deltas)
127
- ? vg.deltas.filter((d) => {
128
- const payload = d === null || d === void 0 ? void 0 : d.payload;
129
- if (payload instanceof Uint8Array)
130
- return payload.byteLength > 0;
131
- if (payload instanceof ArrayBuffer)
132
- return payload.byteLength > 0;
133
- if (typeof payload === "string" && payload.length > 0)
134
- return true;
135
- return false;
126
+ ? vg.deltas.flatMap((delta) => {
127
+ const payload = isValidUint8Array(delta === null || delta === void 0 ? void 0 : delta.payload);
128
+ if (!(payload === null || payload === void 0 ? void 0 : payload.byteLength) || typeof (delta === null || delta === void 0 ? void 0 : delta.baseCheckpointId) !== "string" || !validCheckpointIds.has(delta.baseCheckpointId)) {
129
+ return [];
130
+ }
131
+ return [Object.assign(Object.assign({}, delta), { payload })];
136
132
  })
137
133
  : [];
138
134
  return Object.assign(Object.assign({}, vg), { checkpoints,
@@ -35,10 +35,16 @@ function buildStrokeOptions(element) {
35
35
  last: !!element.lastCommittedPoint,
36
36
  };
37
37
  }
38
+ const normalizeStrokePressure = (pressure) => {
39
+ if (!Number.isFinite(pressure) || pressure === undefined || pressure <= 0) {
40
+ return 0.5;
41
+ }
42
+ return Math.min(1, Math.max(0.05, pressure));
43
+ };
38
44
  function buildInputPoints(element) {
39
45
  return element.simulatePressure
40
- ? element.points.map(({ x, y }, i) => [x.scoped, y.scoped, element.pressures[i]])
41
- : element.points.map(({ x, y }) => [x.scoped, y.scoped]);
46
+ ? element.points.map(({ x, y }) => [x.scoped, y.scoped])
47
+ : element.points.map(({ x, y }, i) => [x.scoped, y.scoped, normalizeStrokePressure(element.pressures[i])]);
42
48
  }
43
49
  export function getFreeDrawSvgPath(element) {
44
50
  if (element.points.length === 0) {
@@ -140,9 +140,21 @@ export const newArrowElement = (currentScope, opts) => {
140
140
  var _a;
141
141
  return (Object.assign(Object.assign({}, _newElementBase("arrow", currentScope, opts)), { type: "arrow", points: opts.points || [], lines: opts.lines || [], pathOverrides: opts.pathOverrides || [], lastCommittedPoint: null, startBinding: null, endBinding: null, elbowed: (_a = opts.elbowed) !== null && _a !== void 0 ? _a : true }));
142
142
  };
143
+ const withDisabledContentVisibility = (items, fallback) => {
144
+ const source = (items === null || items === void 0 ? void 0 : items.length) ? items : [fallback];
145
+ return source.map((item) => (Object.assign(Object.assign({}, item), { content: Object.assign(Object.assign({}, item.content), { visible: false }) })));
146
+ };
147
+ const getMediaElementStyle = (opts) => ({
148
+ stroke: withDisabledContentVisibility(opts.stroke, DEFAULT_ELEMENT_PROPS.stroke),
149
+ background: withDisabledContentVisibility(opts.background, DEFAULT_ELEMENT_PROPS.background),
150
+ });
151
+ const getDocumentElementStyle = (opts) => ({
152
+ stroke: withDisabledContentVisibility(opts.stroke, DEFAULT_ELEMENT_PROPS.stroke),
153
+ background: withDisabledContentVisibility(opts.background, DEFAULT_ELEMENT_PROPS.background),
154
+ });
143
155
  export const newImageElement = (currentScope, opts) => {
144
156
  var _a, _b, _c;
145
- return (Object.assign(Object.assign({}, _newElementBase("image", currentScope, opts)), { type: "image", status: (_a = opts.status) !== null && _a !== void 0 ? _a : IMAGE_STATUS.PENDING, fileId: (_b = opts.fileId) !== null && _b !== void 0 ? _b : null, scaleFlip: (_c = opts.scaleFlip) !== null && _c !== void 0 ? _c : [1, 1], crop: null, filter: null }));
157
+ return (Object.assign(Object.assign({}, _newElementBase("image", currentScope, Object.assign(Object.assign({}, opts), getMediaElementStyle(opts)))), { type: "image", status: (_a = opts.status) !== null && _a !== void 0 ? _a : IMAGE_STATUS.PENDING, fileId: (_b = opts.fileId) !== null && _b !== void 0 ? _b : null, scaleFlip: (_c = opts.scaleFlip) !== null && _c !== void 0 ? _c : [1, 1], crop: null, filter: null }));
146
158
  };
147
159
  export const newTableElement = (currentScope, opts) => {
148
160
  var _a;
@@ -150,7 +162,7 @@ export const newTableElement = (currentScope, opts) => {
150
162
  };
151
163
  export const newDocElement = (currentScope, opts) => {
152
164
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
153
- return (Object.assign(Object.assign({}, _newElementBase("doc", currentScope, opts)), { type: "doc", text: opts.text || "", fileId: (_a = opts.fileId) !== null && _a !== void 0 ? _a : null, gridConfig: {
165
+ return (Object.assign(Object.assign({}, _newElementBase("doc", currentScope, Object.assign(Object.assign({}, opts), getDocumentElementStyle(opts)))), { type: "doc", text: opts.text || "", fileId: (_a = opts.fileId) !== null && _a !== void 0 ? _a : null, gridConfig: {
154
166
  columns: (_c = (_b = opts.gridConfig) === null || _b === void 0 ? void 0 : _b.columns) !== null && _c !== void 0 ? _c : 1,
155
167
  gapX: (_e = (_d = opts.gridConfig) === null || _d === void 0 ? void 0 : _d.gapX) !== null && _e !== void 0 ? _e : 0,
156
168
  gapY: (_g = (_f = opts.gridConfig) === null || _f === void 0 ? void 0 : _f.gapY) !== null && _g !== void 0 ? _g : 0,
@@ -158,8 +170,14 @@ export const newDocElement = (currentScope, opts) => {
158
170
  scale: (_l = (_k = opts.gridConfig) === null || _k === void 0 ? void 0 : _k.scale) !== null && _l !== void 0 ? _l : 1,
159
171
  } }));
160
172
  };
161
- export const newPdfElement = (currentScope, opts) => (Object.assign(Object.assign({ fileId: null, gridConfig: { columns: 1, gapX: 0, gapY: 0, firstPageAlone: false, scale: 1 } }, _newElementBase("pdf", currentScope, opts)), { type: "pdf" }));
162
- export const newModelElement = (currentScope, opts) => (Object.assign(Object.assign({ modelType: null, code: null, thumbnail: null, fileIds: [], viewerState: null }, _newElementBase("model", currentScope, opts)), { type: 'model' }));
173
+ export const newPdfElement = (currentScope, opts) => (Object.assign(Object.assign({ fileId: null, gridConfig: { columns: 1, gapX: 0, gapY: 0, firstPageAlone: false, scale: 1 } }, _newElementBase("pdf", currentScope, Object.assign(Object.assign({}, opts), getDocumentElementStyle(opts)))), { type: "pdf" }));
174
+ export const newModelElement = (currentScope, opts) => {
175
+ const modelStyle = {
176
+ stroke: withDisabledContentVisibility(opts.stroke, DEFAULT_ELEMENT_PROPS.stroke),
177
+ background: withDisabledContentVisibility(opts.background, DEFAULT_ELEMENT_PROPS.background),
178
+ };
179
+ return Object.assign(Object.assign({ modelType: null, code: null, thumbnail: null, fileIds: [], viewerState: null }, _newElementBase("model", currentScope, Object.assign(Object.assign({}, opts), modelStyle))), { type: 'model' });
180
+ };
163
181
  // Simplified deep clone for the purpose of cloning DucElement.
164
182
  //
165
183
  // Only clones plain objects and arrays. Doesn't clone Date, RegExp, Map, Set,
@@ -205,7 +223,8 @@ const _deepCopyElement = (val, depth = 0) => {
205
223
  // we're not cloning non-array & non-plain-object objects because we
206
224
  // don't support them on excalidraw elements yet. If we do, we need to make
207
225
  // sure we start cloning them, so let's warn about it.
208
- if (import.meta.env.DEV) {
226
+ const importMetaEnv = import.meta.env;
227
+ if (importMetaEnv === null || importMetaEnv === void 0 ? void 0 : importMetaEnv.DEV) {
209
228
  if (objectType !== "[object Object]" &&
210
229
  objectType !== "[object Array]" &&
211
230
  objectType.startsWith("[object ")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ducjs",
3
- "version": "3.2.2",
3
+ "version": "3.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",