visio-solid-viewer 0.2.0 → 0.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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { VISIO_RASTER_IMAGE_LIMITS, VISIO_VISIBILITY_LIMITS, getVisioPageLayers, inspectVisioRasterImage, parseVsdx, resolveVisioPageVisibility, validateVisioForeignVector } from "ooxml-core/visio";
1
+ import { VISIO_RASTER_IMAGE_LIMITS, VISIO_VISIBILITY_LIMITS, getVisioPageLayers, inspectVisioRasterImage, loadVisio, resolveVisioPageVisibility, validateVisioForeignVector } from "ooxml-core/visio";
2
2
  import { registerControls } from "ooxml-ui/controls";
3
3
  import { getIcon, registerIcon } from "ooxml-ui/icons";
4
4
  import { className, effect, style, template, use } from "solid-js/web";
@@ -273,7 +273,7 @@ function member(value, choices, label) {
273
273
  }
274
274
  /** Defensive display limits also protect callers supplying their own typed scenes. */
275
275
  function assertViewableDocument(model) {
276
- if (model.format !== "vsdx" || !Array.isArray(model.pages) || model.pages.length > 256 || !Array.isArray(model.diagnostics) || model.diagnostics.length > 2e3) throw new Error("The scene has an invalid page list.");
276
+ if (model.format !== "vsdx" && model.format !== "vsd" || !Array.isArray(model.pages) || model.pages.length > 256 || !Array.isArray(model.diagnostics) || model.diagnostics.length > 2e3) throw new Error("The scene has an invalid page list.");
277
277
  const seen = /* @__PURE__ */ new Set();
278
278
  let pathBytes = 0, textBytes = 0, runCount = 0, imageBytes = 0, geometryCount = 0, uniquePixels = 0, drawnPixels = 0, layerCount = 0, paragraphCount = 0, gradientStops = 0;
279
279
  const imageResources = /* @__PURE__ */ new Map();
@@ -535,7 +535,7 @@ function createWorkerEditor(factory, timeoutMs = 2e4) {
535
535
  if (typeof Worker === "undefined") throw new Error("Editing requires browser worker support.");
536
536
  return new Worker(new URL(
537
537
  /* @vite-ignore */
538
- new URL("assets/edit-worker-BcXrV_St.js", import.meta.url).href,
538
+ new URL("assets/edit-worker-CZbtTOr4.js", import.meta.url).href,
539
539
  "" + import.meta.url
540
540
  ), { type: "module" });
541
541
  });
@@ -791,9 +791,10 @@ var ViewerController = class {
791
791
  #sourceGeneration = 0;
792
792
  #searchIndex = null;
793
793
  #history = null;
794
+ #sourceFormat = null;
794
795
  #editId = 0;
795
796
  #visible = documentVisibility(null);
796
- constructor(parser = parseVsdx, listenerError = (error) => {
797
+ constructor(parser = loadVisio, listenerError = (error) => {
797
798
  if (typeof globalThis.reportError === "function") globalThis.reportError(error);
798
799
  else console.error("Visio viewer listener failed:", error);
799
800
  }, editor = createWorkerEditor()) {
@@ -833,6 +834,7 @@ var ViewerController = class {
833
834
  ++this.#sourceGeneration;
834
835
  this.#invalidateEdit();
835
836
  this.#history = null;
837
+ this.#sourceFormat = null;
836
838
  this.#loadId++;
837
839
  this.parser.cancel?.();
838
840
  this.#searchIndex = null;
@@ -975,7 +977,7 @@ var ViewerController = class {
975
977
  this.#change({
976
978
  loading: true,
977
979
  error: null,
978
- edit: this.#history?.state ?? EMPTY_EDIT_STATE
980
+ edit: this.#sourceEditState()
979
981
  });
980
982
  if (this.#destroyed || id !== this.#loadId) return;
981
983
  let document;
@@ -986,10 +988,10 @@ var ViewerController = class {
986
988
  if (this.#destroyed || id !== this.#loadId) return;
987
989
  if (bytes.byteLength > 33554432) throw new Error("This viewer accepts files up to 32 MiB.");
988
990
  const owned = bytes instanceof Uint8Array ? Uint8Array.from(bytes) : new Uint8Array(bytes.slice(0));
989
- history = new DocumentHistory(owned);
990
991
  document = await this.parser(Uint8Array.from(owned));
991
992
  if (this.#destroyed || id !== this.#loadId) return;
992
993
  assertViewableDocument(document);
994
+ history = new DocumentHistory(owned);
993
995
  visible = documentVisibility(document);
994
996
  } catch (cause) {
995
997
  if (this.#destroyed || id !== this.#loadId) return;
@@ -1002,13 +1004,14 @@ var ViewerController = class {
1002
1004
  throw error;
1003
1005
  }
1004
1006
  this.#history = history;
1007
+ this.#sourceFormat = document.format;
1005
1008
  this.#searchIndex = null;
1006
1009
  this.#visible = visible;
1007
1010
  ++this.#documentGeneration;
1008
1011
  ++this.#sourceGeneration;
1009
1012
  this.#change({
1010
1013
  document,
1011
- edit: history.state,
1014
+ edit: document.format === "vsdx" ? history.state : EMPTY_EDIT_STATE,
1012
1015
  pageIndex: 0,
1013
1016
  loading: false,
1014
1017
  error: null,
@@ -1025,7 +1028,7 @@ var ViewerController = class {
1025
1028
  this.#invalidateEdit();
1026
1029
  this.#change({
1027
1030
  loading: false,
1028
- edit: this.#history?.state ?? EMPTY_EDIT_STATE
1031
+ edit: this.#sourceEditState()
1029
1032
  });
1030
1033
  }
1031
1034
  destroy() {
@@ -1033,6 +1036,7 @@ var ViewerController = class {
1033
1036
  this.#destroyed = true;
1034
1037
  this.#invalidateEdit();
1035
1038
  this.#history = null;
1039
+ this.#sourceFormat = null;
1036
1040
  ++this.#documentGeneration;
1037
1041
  ++this.#sourceGeneration;
1038
1042
  ++this.#loadId;
@@ -1077,11 +1081,11 @@ var ViewerController = class {
1077
1081
  if (!this.#state.edit.busy) return;
1078
1082
  this.#invalidateEdit();
1079
1083
  this.parser.cancel?.();
1080
- this.#change({ edit: this.#history?.state ?? EMPTY_EDIT_STATE });
1084
+ this.#change({ edit: this.#sourceEditState() });
1081
1085
  }
1082
1086
  exportVsdx() {
1083
1087
  this.#assertAlive();
1084
- if (!this.#history) throw new Error("Load a VSDX file before downloading a source-backed copy.");
1088
+ if (!this.#history || this.#sourceFormat !== "vsdx" || this.#state.document?.format !== "vsdx") throw new Error("Load a VSDX file before downloading a source-backed copy.");
1085
1089
  if (this.#state.edit.busy || this.#state.loading) throw new Error("Wait for the current document operation before downloading.");
1086
1090
  return this.#history.export();
1087
1091
  }
@@ -1089,10 +1093,13 @@ var ViewerController = class {
1089
1093
  ++this.#editId;
1090
1094
  this.editor.cancel?.();
1091
1095
  }
1096
+ #sourceEditState() {
1097
+ return this.#sourceFormat === "vsdx" && this.#state.document?.format === "vsdx" ? this.#history?.state ?? EMPTY_EDIT_STATE : EMPTY_EDIT_STATE;
1098
+ }
1092
1099
  async #mutate(kind, commands) {
1093
1100
  this.#assertAlive();
1094
1101
  const history = this.#history;
1095
- if (!history) throw new Error("Load a VSDX file before editing. Model-only documents are read only.");
1102
+ if (!history || this.#sourceFormat !== "vsdx" || this.#state.document?.format !== "vsdx") throw new Error("Load a VSDX file before editing. Model-only documents are read only.");
1096
1103
  if (this.#state.loading || this.#state.edit.busy) throw new Error("Another document operation is in progress.");
1097
1104
  const target = kind === "undo" ? history.undoTarget : kind === "redo" ? history.redoTarget : void 0;
1098
1105
  if (kind !== "edit" && !target) return;
@@ -1118,6 +1125,7 @@ var ViewerController = class {
1118
1125
  } else document = await this.parser(Uint8Array.from(target.bytes));
1119
1126
  assertCurrent();
1120
1127
  assertViewableDocument(document);
1128
+ if (document.format !== "vsdx") throw new Error("A VSDX edit or history operation cannot change the source format.");
1121
1129
  if (edited && !edited.changedParts.length) {
1122
1130
  this.#change({ edit: history.state });
1123
1131
  return;
@@ -1207,10 +1215,10 @@ var eventKeys = [
1207
1215
  //#region src/worker-parser.ts
1208
1216
  /** One disposable worker per document prevents old parses and long CPU tasks from occupying the UI. */
1209
1217
  function createWorkerParser(factory, timeoutMs = 15e3) {
1210
- if (!factory && typeof Worker === "undefined") return parseVsdx;
1218
+ if (!factory && typeof Worker === "undefined") return loadVisio;
1211
1219
  const create = factory ?? (() => new Worker(new URL(
1212
1220
  /* @vite-ignore */
1213
- new URL("assets/parse-worker-B8EBQQpD.js", import.meta.url).href,
1221
+ new URL("assets/parse-worker-BEaLqUCJ.js", import.meta.url).href,
1214
1222
  "" + import.meta.url
1215
1223
  ), { type: "module" }));
1216
1224
  let cancel;
@@ -4622,7 +4630,7 @@ var VisioViewerElement = class extends BaseElement {
4622
4630
  empty.className = "empty";
4623
4631
  const heading = document.createElement("strong");
4624
4632
  heading.textContent = "Open a Visio drawing";
4625
- empty.append(heading, "Open a .vsdx file to start. Files stay in this browser.");
4633
+ empty.append(heading, "Open a .vsdx or supported .vsd file to start. Files stay in this browser.");
4626
4634
  this.#viewport.replaceChildren(empty);
4627
4635
  }
4628
4636
  const notes = compatibilityNotes(state.document?.diagnostics ?? [], this.#renderWarnings);
@@ -1,4 +1,4 @@
1
- import { VISIO_RASTER_IMAGE_LIMITS, VISIO_VISIBILITY_LIMITS, getVisioPageLayers, inspectVisioRasterImage, parseVsdx, resolveVisioPageVisibility, validateVisioForeignVector } from "ooxml-core/visio";
1
+ import { VISIO_RASTER_IMAGE_LIMITS, VISIO_VISIBILITY_LIMITS, getVisioPageLayers, inspectVisioRasterImage, loadVisio, resolveVisioPageVisibility, validateVisioForeignVector } from "ooxml-core/visio";
2
2
  import { registerControls } from "ooxml-ui/controls";
3
3
  import { getIcon, registerIcon } from "ooxml-ui/icons";
4
4
  import { escape, ssr, ssrAttribute, ssrHydrationKey, ssrStyle } from "solid-js/web";
@@ -273,7 +273,7 @@ function member(value, choices, label) {
273
273
  }
274
274
  /** Defensive display limits also protect callers supplying their own typed scenes. */
275
275
  function assertViewableDocument(model) {
276
- if (model.format !== "vsdx" || !Array.isArray(model.pages) || model.pages.length > 256 || !Array.isArray(model.diagnostics) || model.diagnostics.length > 2e3) throw new Error("The scene has an invalid page list.");
276
+ if (model.format !== "vsdx" && model.format !== "vsd" || !Array.isArray(model.pages) || model.pages.length > 256 || !Array.isArray(model.diagnostics) || model.diagnostics.length > 2e3) throw new Error("The scene has an invalid page list.");
277
277
  const seen = /* @__PURE__ */ new Set();
278
278
  let pathBytes = 0, textBytes = 0, runCount = 0, imageBytes = 0, geometryCount = 0, uniquePixels = 0, drawnPixels = 0, layerCount = 0, paragraphCount = 0, gradientStops = 0;
279
279
  const imageResources = /* @__PURE__ */ new Map();
@@ -787,9 +787,10 @@ var ViewerController = class {
787
787
  #sourceGeneration = 0;
788
788
  #searchIndex = null;
789
789
  #history = null;
790
+ #sourceFormat = null;
790
791
  #editId = 0;
791
792
  #visible = documentVisibility(null);
792
- constructor(parser = parseVsdx, listenerError = (error) => {
793
+ constructor(parser = loadVisio, listenerError = (error) => {
793
794
  if (typeof globalThis.reportError === "function") globalThis.reportError(error);
794
795
  else console.error("Visio viewer listener failed:", error);
795
796
  }, editor = createWorkerEditor()) {
@@ -829,6 +830,7 @@ var ViewerController = class {
829
830
  ++this.#sourceGeneration;
830
831
  this.#invalidateEdit();
831
832
  this.#history = null;
833
+ this.#sourceFormat = null;
832
834
  this.#loadId++;
833
835
  this.parser.cancel?.();
834
836
  this.#searchIndex = null;
@@ -971,7 +973,7 @@ var ViewerController = class {
971
973
  this.#change({
972
974
  loading: true,
973
975
  error: null,
974
- edit: this.#history?.state ?? EMPTY_EDIT_STATE
976
+ edit: this.#sourceEditState()
975
977
  });
976
978
  if (this.#destroyed || id !== this.#loadId) return;
977
979
  let document;
@@ -982,10 +984,10 @@ var ViewerController = class {
982
984
  if (this.#destroyed || id !== this.#loadId) return;
983
985
  if (bytes.byteLength > 33554432) throw new Error("This viewer accepts files up to 32 MiB.");
984
986
  const owned = bytes instanceof Uint8Array ? Uint8Array.from(bytes) : new Uint8Array(bytes.slice(0));
985
- history = new DocumentHistory(owned);
986
987
  document = await this.parser(Uint8Array.from(owned));
987
988
  if (this.#destroyed || id !== this.#loadId) return;
988
989
  assertViewableDocument(document);
990
+ history = new DocumentHistory(owned);
989
991
  visible = documentVisibility(document);
990
992
  } catch (cause) {
991
993
  if (this.#destroyed || id !== this.#loadId) return;
@@ -998,13 +1000,14 @@ var ViewerController = class {
998
1000
  throw error;
999
1001
  }
1000
1002
  this.#history = history;
1003
+ this.#sourceFormat = document.format;
1001
1004
  this.#searchIndex = null;
1002
1005
  this.#visible = visible;
1003
1006
  ++this.#documentGeneration;
1004
1007
  ++this.#sourceGeneration;
1005
1008
  this.#change({
1006
1009
  document,
1007
- edit: history.state,
1010
+ edit: document.format === "vsdx" ? history.state : EMPTY_EDIT_STATE,
1008
1011
  pageIndex: 0,
1009
1012
  loading: false,
1010
1013
  error: null,
@@ -1021,7 +1024,7 @@ var ViewerController = class {
1021
1024
  this.#invalidateEdit();
1022
1025
  this.#change({
1023
1026
  loading: false,
1024
- edit: this.#history?.state ?? EMPTY_EDIT_STATE
1027
+ edit: this.#sourceEditState()
1025
1028
  });
1026
1029
  }
1027
1030
  destroy() {
@@ -1029,6 +1032,7 @@ var ViewerController = class {
1029
1032
  this.#destroyed = true;
1030
1033
  this.#invalidateEdit();
1031
1034
  this.#history = null;
1035
+ this.#sourceFormat = null;
1032
1036
  ++this.#documentGeneration;
1033
1037
  ++this.#sourceGeneration;
1034
1038
  ++this.#loadId;
@@ -1073,11 +1077,11 @@ var ViewerController = class {
1073
1077
  if (!this.#state.edit.busy) return;
1074
1078
  this.#invalidateEdit();
1075
1079
  this.parser.cancel?.();
1076
- this.#change({ edit: this.#history?.state ?? EMPTY_EDIT_STATE });
1080
+ this.#change({ edit: this.#sourceEditState() });
1077
1081
  }
1078
1082
  exportVsdx() {
1079
1083
  this.#assertAlive();
1080
- if (!this.#history) throw new Error("Load a VSDX file before downloading a source-backed copy.");
1084
+ if (!this.#history || this.#sourceFormat !== "vsdx" || this.#state.document?.format !== "vsdx") throw new Error("Load a VSDX file before downloading a source-backed copy.");
1081
1085
  if (this.#state.edit.busy || this.#state.loading) throw new Error("Wait for the current document operation before downloading.");
1082
1086
  return this.#history.export();
1083
1087
  }
@@ -1085,10 +1089,13 @@ var ViewerController = class {
1085
1089
  ++this.#editId;
1086
1090
  this.editor.cancel?.();
1087
1091
  }
1092
+ #sourceEditState() {
1093
+ return this.#sourceFormat === "vsdx" && this.#state.document?.format === "vsdx" ? this.#history?.state ?? EMPTY_EDIT_STATE : EMPTY_EDIT_STATE;
1094
+ }
1088
1095
  async #mutate(kind, commands) {
1089
1096
  this.#assertAlive();
1090
1097
  const history = this.#history;
1091
- if (!history) throw new Error("Load a VSDX file before editing. Model-only documents are read only.");
1098
+ if (!history || this.#sourceFormat !== "vsdx" || this.#state.document?.format !== "vsdx") throw new Error("Load a VSDX file before editing. Model-only documents are read only.");
1092
1099
  if (this.#state.loading || this.#state.edit.busy) throw new Error("Another document operation is in progress.");
1093
1100
  const target = kind === "undo" ? history.undoTarget : kind === "redo" ? history.redoTarget : void 0;
1094
1101
  if (kind !== "edit" && !target) return;
@@ -1114,6 +1121,7 @@ var ViewerController = class {
1114
1121
  } else document = await this.parser(Uint8Array.from(target.bytes));
1115
1122
  assertCurrent();
1116
1123
  assertViewableDocument(document);
1124
+ if (document.format !== "vsdx") throw new Error("A VSDX edit or history operation cannot change the source format.");
1117
1125
  if (edited && !edited.changedParts.length) {
1118
1126
  this.#change({ edit: history.state });
1119
1127
  return;
@@ -1203,7 +1211,7 @@ var eventKeys = [
1203
1211
  //#region src/worker-parser.ts
1204
1212
  /** One disposable worker per document prevents old parses and long CPU tasks from occupying the UI. */
1205
1213
  function createWorkerParser(factory, timeoutMs = 15e3) {
1206
- if (!factory && typeof Worker === "undefined") return parseVsdx;
1214
+ if (!factory && typeof Worker === "undefined") return loadVisio;
1207
1215
  const create = factory ?? (() => new Worker(new URL("./parse-worker.js", import.meta.url), { type: "module" }));
1208
1216
  let cancel;
1209
1217
  const parse = (bytes) => {
@@ -4614,7 +4622,7 @@ var VisioViewerElement = class extends BaseElement {
4614
4622
  empty.className = "empty";
4615
4623
  const heading = document.createElement("strong");
4616
4624
  heading.textContent = "Open a Visio drawing";
4617
- empty.append(heading, "Open a .vsdx file to start. Files stay in this browser.");
4625
+ empty.append(heading, "Open a .vsdx or supported .vsd file to start. Files stay in this browser.");
4618
4626
  this.#viewport.replaceChildren(empty);
4619
4627
  }
4620
4628
  const notes = compatibilityNotes(state.document?.diagnostics ?? [], this.#renderWarnings);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "visio-solid-viewer",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Local-first Visio viewer for solid",
5
5
  "homepage": "https://christophervr.github.io/visio-viewer/",
6
6
  "license": "Apache-2.0",
@@ -29,9 +29,9 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "emf-converter": "4.8.9",
32
- "ooxml-core": "^0.12.0",
33
- "ooxml-ui": "^0.2.0",
34
- "visio-core": "^0.2.0"
32
+ "ooxml-core": "^0.13.0",
33
+ "ooxml-ui": "^0.4.1",
34
+ "visio-core": "^0.2.1"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "solid-js": "^1.9.0"