@pooder/kit 5.0.2 → 5.0.4

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.mjs CHANGED
@@ -2954,6 +2954,8 @@ var FeatureTool = class {
2954
2954
  this.workingFeatures = [];
2955
2955
  this.isUpdatingConfig = false;
2956
2956
  this.isToolActive = false;
2957
+ this.isFeatureSessionActive = false;
2958
+ this.sessionOriginalFeatures = null;
2957
2959
  this.hasWorkingChanges = false;
2958
2960
  this.handleMoving = null;
2959
2961
  this.handleModified = null;
@@ -2961,6 +2963,9 @@ var FeatureTool = class {
2961
2963
  this.currentGeometry = null;
2962
2964
  this.onToolActivated = (event) => {
2963
2965
  this.isToolActive = event.id === this.id;
2966
+ if (!this.isToolActive) {
2967
+ this.restoreSessionFeaturesToConfig();
2968
+ }
2964
2969
  this.updateVisibility();
2965
2970
  };
2966
2971
  if (options) {
@@ -2984,6 +2989,7 @@ var FeatureTool = class {
2984
2989
  configService.onAnyChange((e) => {
2985
2990
  if (this.isUpdatingConfig) return;
2986
2991
  if (e.key === "dieline.features") {
2992
+ if (this.isFeatureSessionActive) return;
2987
2993
  const next = e.value || [];
2988
2994
  this.workingFeatures = this.cloneFeatures(next);
2989
2995
  this.hasWorkingChanges = false;
@@ -3003,6 +3009,7 @@ var FeatureTool = class {
3003
3009
  deactivate(context) {
3004
3010
  var _a;
3005
3011
  context.eventBus.off("tool:activated", this.onToolActivated);
3012
+ this.restoreSessionFeaturesToConfig();
3006
3013
  (_a = this.dirtyTrackerDisposable) == null ? void 0 : _a.dispose();
3007
3014
  this.dirtyTrackerDisposable = void 0;
3008
3015
  this.teardown();
@@ -3034,9 +3041,9 @@ var FeatureTool = class {
3034
3041
  name: "Feature",
3035
3042
  interaction: "session",
3036
3043
  commands: {
3037
- begin: "resetWorkingFeatures",
3044
+ begin: "beginFeatureSession",
3038
3045
  commit: "completeFeatures",
3039
- rollback: "resetWorkingFeatures"
3046
+ rollback: "rollbackFeatureSession"
3040
3047
  },
3041
3048
  session: {
3042
3049
  autoBegin: false,
@@ -3045,6 +3052,25 @@ var FeatureTool = class {
3045
3052
  }
3046
3053
  ],
3047
3054
  [ContributionPointIds4.COMMANDS]: [
3055
+ {
3056
+ command: "beginFeatureSession",
3057
+ title: "Begin Feature Session",
3058
+ handler: async () => {
3059
+ if (this.isFeatureSessionActive) {
3060
+ return { ok: true };
3061
+ }
3062
+ const original = this.getCommittedFeatures();
3063
+ this.sessionOriginalFeatures = this.cloneFeatures(original);
3064
+ this.isFeatureSessionActive = true;
3065
+ await this.refreshGeometry();
3066
+ this.setWorkingFeatures(this.cloneFeatures(original));
3067
+ this.hasWorkingChanges = false;
3068
+ this.redraw();
3069
+ this.emitWorkingChange();
3070
+ this.updateCommittedFeatures([]);
3071
+ return { ok: true };
3072
+ }
3073
+ },
3048
3074
  {
3049
3075
  command: "addFeature",
3050
3076
  title: "Add Edge Feature",
@@ -3097,19 +3123,27 @@ var FeatureTool = class {
3097
3123
  }
3098
3124
  },
3099
3125
  {
3100
- command: "resetWorkingFeatures",
3101
- title: "Reset Working Features",
3126
+ command: "rollbackFeatureSession",
3127
+ title: "Rollback Feature Session",
3102
3128
  handler: async () => {
3103
- var _a;
3104
- const configService = (_a = this.context) == null ? void 0 : _a.services.get(
3105
- "ConfigurationService"
3129
+ const original = this.cloneFeatures(
3130
+ this.sessionOriginalFeatures || this.getCommittedFeatures()
3106
3131
  );
3107
- const next = (configService == null ? void 0 : configService.get("dieline.features", [])) || [];
3108
3132
  await this.refreshGeometry();
3109
- this.setWorkingFeatures(this.cloneFeatures(next));
3133
+ this.setWorkingFeatures(original);
3110
3134
  this.hasWorkingChanges = false;
3111
3135
  this.redraw();
3112
3136
  this.emitWorkingChange();
3137
+ this.updateCommittedFeatures(original);
3138
+ this.clearFeatureSessionState();
3139
+ return { ok: true };
3140
+ }
3141
+ },
3142
+ {
3143
+ command: "resetWorkingFeatures",
3144
+ title: "Reset Working Features",
3145
+ handler: async () => {
3146
+ await this.resetWorkingFeaturesFromSource();
3113
3147
  return { ok: true };
3114
3148
  }
3115
3149
  },
@@ -3133,6 +3167,37 @@ var FeatureTool = class {
3133
3167
  cloneFeatures(features) {
3134
3168
  return JSON.parse(JSON.stringify(features || []));
3135
3169
  }
3170
+ getConfigService() {
3171
+ var _a;
3172
+ return (_a = this.context) == null ? void 0 : _a.services.get("ConfigurationService");
3173
+ }
3174
+ getCommittedFeatures() {
3175
+ const configService = this.getConfigService();
3176
+ const committed = (configService == null ? void 0 : configService.get("dieline.features", [])) || [];
3177
+ return this.cloneFeatures(committed);
3178
+ }
3179
+ updateCommittedFeatures(next) {
3180
+ const configService = this.getConfigService();
3181
+ if (!configService) return;
3182
+ this.isUpdatingConfig = true;
3183
+ try {
3184
+ configService.update("dieline.features", next);
3185
+ } finally {
3186
+ this.isUpdatingConfig = false;
3187
+ }
3188
+ }
3189
+ clearFeatureSessionState() {
3190
+ this.isFeatureSessionActive = false;
3191
+ this.sessionOriginalFeatures = null;
3192
+ }
3193
+ restoreSessionFeaturesToConfig() {
3194
+ if (!this.isFeatureSessionActive) return;
3195
+ const original = this.cloneFeatures(
3196
+ this.sessionOriginalFeatures || this.getCommittedFeatures()
3197
+ );
3198
+ this.updateCommittedFeatures(original);
3199
+ this.clearFeatureSessionState();
3200
+ }
3136
3201
  emitWorkingChange() {
3137
3202
  var _a;
3138
3203
  (_a = this.context) == null ? void 0 : _a.eventBus.emit("feature:working:change", {
@@ -3151,6 +3216,16 @@ var FeatureTool = class {
3151
3216
  } catch (e) {
3152
3217
  }
3153
3218
  }
3219
+ async resetWorkingFeaturesFromSource() {
3220
+ const next = this.cloneFeatures(
3221
+ this.isFeatureSessionActive && this.sessionOriginalFeatures ? this.sessionOriginalFeatures : this.getCommittedFeatures()
3222
+ );
3223
+ await this.refreshGeometry();
3224
+ this.setWorkingFeatures(next);
3225
+ this.hasWorkingChanges = false;
3226
+ this.redraw();
3227
+ this.emitWorkingChange();
3228
+ }
3154
3229
  setWorkingFeatures(next) {
3155
3230
  this.workingFeatures = next;
3156
3231
  }
@@ -3207,12 +3282,7 @@ var FeatureTool = class {
3207
3282
  this.workingFeatures,
3208
3283
  { dielineWidth, dielineHeight },
3209
3284
  (next) => {
3210
- this.isUpdatingConfig = true;
3211
- try {
3212
- configService.update("dieline.features", next);
3213
- } finally {
3214
- this.isUpdatingConfig = false;
3215
- }
3285
+ this.updateCommittedFeatures(next);
3216
3286
  this.workingFeatures = this.cloneFeatures(next);
3217
3287
  this.emitWorkingChange();
3218
3288
  }
@@ -3224,6 +3294,7 @@ var FeatureTool = class {
3224
3294
  };
3225
3295
  }
3226
3296
  this.hasWorkingChanges = false;
3297
+ this.clearFeatureSessionState();
3227
3298
  this.redraw();
3228
3299
  return { ok: true };
3229
3300
  }
@@ -3670,7 +3741,6 @@ import {
3670
3741
  import { Canvas as FabricCanvas2, Image as FabricImage, Point as Point2 } from "fabric";
3671
3742
  var IMAGE_OBJECT_LAYER_ID2 = "image.user";
3672
3743
  var IMAGE_OVERLAY_LAYER_ID = "image-overlay";
3673
- var IMAGE_REPLACE_GUARD_MS = 2500;
3674
3744
  var ImageTool = class {
3675
3745
  constructor() {
3676
3746
  this.id = "pooder.kit.image";
@@ -3686,18 +3756,15 @@ var ImageTool = class {
3686
3756
  this.isToolActive = false;
3687
3757
  this.isImageSelectionActive = false;
3688
3758
  this.focusedImageId = null;
3689
- this.suppressSelectionClearUntil = 0;
3690
3759
  this.renderSeq = 0;
3691
3760
  this.onToolActivated = (event) => {
3692
3761
  const before = this.isToolActive;
3693
3762
  this.syncToolActiveFromWorkbench(event.id);
3694
3763
  if (!this.isToolActive) {
3695
- const now = Date.now();
3696
- const inGuardWindow = now <= this.suppressSelectionClearUntil && !!this.focusedImageId;
3697
- if (!inGuardWindow) {
3698
- this.isImageSelectionActive = false;
3699
- this.focusedImageId = null;
3700
- }
3764
+ this.setImageFocus(null, {
3765
+ syncCanvasSelection: true,
3766
+ skipRender: true
3767
+ });
3701
3768
  }
3702
3769
  this.debug("tool:activated", {
3703
3770
  id: event.id,
@@ -3705,8 +3772,7 @@ var ImageTool = class {
3705
3772
  reason: event.reason,
3706
3773
  before,
3707
3774
  isToolActive: this.isToolActive,
3708
- focusedImageId: this.focusedImageId,
3709
- suppressSelectionClearUntil: this.suppressSelectionClearUntil
3775
+ focusedImageId: this.focusedImageId
3710
3776
  });
3711
3777
  if (!this.isToolActive && this.isDebugEnabled()) {
3712
3778
  console.trace("[ImageTool] tool deactivated trace");
@@ -3745,16 +3811,10 @@ var ImageTool = class {
3745
3811
  this.updateImages();
3746
3812
  };
3747
3813
  this.onSelectionCleared = () => {
3748
- const now = Date.now();
3749
- if (now <= this.suppressSelectionClearUntil && this.focusedImageId) {
3750
- this.debug("selection:cleared ignored", {
3751
- suppressUntil: this.suppressSelectionClearUntil,
3752
- focusedImageId: this.focusedImageId
3753
- });
3754
- return;
3755
- }
3756
- this.isImageSelectionActive = false;
3757
- this.focusedImageId = null;
3814
+ this.setImageFocus(null, {
3815
+ syncCanvasSelection: false,
3816
+ skipRender: true
3817
+ });
3758
3818
  this.debug("selection:cleared applied");
3759
3819
  this.updateImages();
3760
3820
  };
@@ -3910,7 +3970,7 @@ var ImageTool = class {
3910
3970
  id: "image.frame.strokeColor",
3911
3971
  type: "color",
3912
3972
  label: "Image Frame Stroke Color",
3913
- default: "#FF0000"
3973
+ default: "#808080"
3914
3974
  },
3915
3975
  {
3916
3976
  id: "image.frame.strokeWidth",
@@ -3926,7 +3986,7 @@ var ImageTool = class {
3926
3986
  type: "select",
3927
3987
  label: "Image Frame Stroke Style",
3928
3988
  options: ["solid", "dashed", "hidden"],
3929
- default: "solid"
3989
+ default: "dashed"
3930
3990
  },
3931
3991
  {
3932
3992
  id: "image.frame.dashLength",
@@ -4021,6 +4081,13 @@ var ImageTool = class {
4021
4081
  await this.fitImageToDefaultArea(id);
4022
4082
  }
4023
4083
  },
4084
+ {
4085
+ command: "focusImage",
4086
+ title: "Focus Image",
4087
+ handler: (id, options = {}) => {
4088
+ return this.setImageFocus(id, options);
4089
+ }
4090
+ },
4024
4091
  {
4025
4092
  command: "removeImage",
4026
4093
  title: "Remove Image",
@@ -4030,8 +4097,10 @@ var ImageTool = class {
4030
4097
  if (next.length !== this.items.length) {
4031
4098
  this.purgeSourceSizeCacheForItem(removed);
4032
4099
  if (this.focusedImageId === id) {
4033
- this.focusedImageId = null;
4034
- this.isImageSelectionActive = false;
4100
+ this.setImageFocus(null, {
4101
+ syncCanvasSelection: true,
4102
+ skipRender: true
4103
+ });
4035
4104
  }
4036
4105
  this.updateConfig(next);
4037
4106
  }
@@ -4049,8 +4118,10 @@ var ImageTool = class {
4049
4118
  title: "Clear Images",
4050
4119
  handler: () => {
4051
4120
  this.sourceSizeBySrc.clear();
4052
- this.focusedImageId = null;
4053
- this.isImageSelectionActive = false;
4121
+ this.setImageFocus(null, {
4122
+ syncCanvasSelection: true,
4123
+ skipRender: true
4124
+ });
4054
4125
  this.updateConfig([]);
4055
4126
  }
4056
4127
  },
@@ -4115,22 +4186,38 @@ var ImageTool = class {
4115
4186
  generateId() {
4116
4187
  return Math.random().toString(36).substring(2, 9);
4117
4188
  }
4118
- getImageIdFromActiveObject() {
4119
- var _a, _b, _c;
4120
- const active = (_a = this.canvasService) == null ? void 0 : _a.canvas.getActiveObject();
4121
- if (((_b = active == null ? void 0 : active.data) == null ? void 0 : _b.layerId) === IMAGE_OBJECT_LAYER_ID2 && typeof ((_c = active == null ? void 0 : active.data) == null ? void 0 : _c.id) === "string") {
4122
- return active.data.id;
4123
- }
4124
- return null;
4189
+ hasImageItem(id) {
4190
+ return this.items.some((item) => item.id === id) || this.workingItems.some((item) => item.id === id);
4125
4191
  }
4126
- resolveReplaceTargetId(explicitId) {
4127
- const has = (id) => !!id && this.items.some((item) => item.id === id);
4128
- if (has(explicitId)) return explicitId;
4129
- if (has(this.focusedImageId)) return this.focusedImageId;
4130
- const activeId = this.getImageIdFromActiveObject();
4131
- if (has(activeId)) return activeId;
4132
- if (this.items.length === 1) return this.items[0].id;
4133
- return null;
4192
+ setImageFocus(id, options = {}) {
4193
+ const syncCanvasSelection = options.syncCanvasSelection !== false;
4194
+ if (id && !this.hasImageItem(id)) {
4195
+ return { ok: false, reason: "image-not-found" };
4196
+ }
4197
+ this.focusedImageId = id;
4198
+ this.isImageSelectionActive = !!id;
4199
+ if (syncCanvasSelection && this.canvasService) {
4200
+ const canvas = this.canvasService.canvas;
4201
+ if (!id) {
4202
+ canvas.discardActiveObject();
4203
+ } else {
4204
+ const obj = this.getImageObject(id);
4205
+ if (obj) {
4206
+ obj.set({
4207
+ selectable: true,
4208
+ evented: true,
4209
+ hasControls: true,
4210
+ hasBorders: true
4211
+ });
4212
+ canvas.setActiveObject(obj);
4213
+ }
4214
+ }
4215
+ this.canvasService.requestRenderAll();
4216
+ }
4217
+ if (!options.skipRender) {
4218
+ this.updateImages();
4219
+ }
4220
+ return { ok: true, id };
4134
4221
  }
4135
4222
  async addImageEntry(url, options, fitOnAdd = true) {
4136
4223
  const id = this.generateId();
@@ -4140,9 +4227,6 @@ var ImageTool = class {
4140
4227
  opacity: 1,
4141
4228
  ...options
4142
4229
  });
4143
- this.focusedImageId = id;
4144
- this.isImageSelectionActive = true;
4145
- this.suppressSelectionClearUntil = Date.now() + IMAGE_REPLACE_GUARD_MS;
4146
4230
  const sessionDirtyBeforeAdd = this.isToolActive && this.hasWorkingChanges;
4147
4231
  const waitLoaded = this.waitImageLoaded(id, true);
4148
4232
  this.updateConfig([...this.items, newItem]);
@@ -4152,26 +4236,24 @@ var ImageTool = class {
4152
4236
  await this.fitImageToDefaultArea(id);
4153
4237
  }
4154
4238
  if (loaded) {
4155
- this.focusImageSelection(id);
4239
+ this.setImageFocus(id);
4156
4240
  }
4157
4241
  return id;
4158
4242
  }
4159
4243
  async upsertImageEntry(url, options = {}) {
4160
- var _a;
4161
- const mode = options.mode || "auto";
4244
+ const mode = options.mode || (options.id ? "replace" : "add");
4162
4245
  const fitOnAdd = options.fitOnAdd !== false;
4163
- if (mode === "add") {
4164
- const id2 = await this.addImageEntry(url, options.addOptions, fitOnAdd);
4165
- return { id: id2, mode: "add" };
4166
- }
4167
- const targetId = this.resolveReplaceTargetId((_a = options.id) != null ? _a : null);
4168
- if (targetId) {
4246
+ if (mode === "replace") {
4247
+ if (!options.id) {
4248
+ throw new Error("replace-target-id-required");
4249
+ }
4250
+ const targetId = options.id;
4251
+ if (!this.hasImageItem(targetId)) {
4252
+ throw new Error("replace-target-not-found");
4253
+ }
4169
4254
  await this.updateImageInConfig(targetId, { url });
4170
4255
  return { id: targetId, mode: "replace" };
4171
4256
  }
4172
- if (mode === "replace" || options.createIfMissing === false) {
4173
- throw new Error("replace-target-not-found");
4174
- }
4175
4257
  const id = await this.addImageEntry(url, options.addOptions, fitOnAdd);
4176
4258
  return { id, mode: "add" };
4177
4259
  }
@@ -4346,9 +4428,9 @@ var ImageTool = class {
4346
4428
  var _a, _b;
4347
4429
  const strokeStyleRaw = this.getConfig(
4348
4430
  "image.frame.strokeStyle",
4349
- "solid"
4350
- ) || "solid";
4351
- const strokeStyle = strokeStyleRaw === "dashed" || strokeStyleRaw === "hidden" ? strokeStyleRaw : "solid";
4431
+ "dashed"
4432
+ ) || "dashed";
4433
+ const strokeStyle = strokeStyleRaw === "dashed" || strokeStyleRaw === "hidden" ? strokeStyleRaw : "dashed";
4352
4434
  const strokeWidth = Number(
4353
4435
  (_a = this.getConfig("image.frame.strokeWidth", 2)) != null ? _a : 2
4354
4436
  );
@@ -4356,7 +4438,7 @@ var ImageTool = class {
4356
4438
  (_b = this.getConfig("image.frame.dashLength", 8)) != null ? _b : 8
4357
4439
  );
4358
4440
  return {
4359
- strokeColor: this.getConfig("image.frame.strokeColor", "#FF0000") || "#FF0000",
4441
+ strokeColor: this.getConfig("image.frame.strokeColor", "#808080") || "#808080",
4360
4442
  strokeWidth: Number.isFinite(strokeWidth) ? Math.max(0, strokeWidth) : 2,
4361
4443
  strokeStyle,
4362
4444
  dashLength: Number.isFinite(dashLength) ? Math.max(1, dashLength) : 8,
@@ -4621,8 +4703,10 @@ var ImageTool = class {
4621
4703
  const frame = this.getFrameRect();
4622
4704
  const desiredIds = new Set(renderItems.map((item) => item.id));
4623
4705
  if (this.focusedImageId && !desiredIds.has(this.focusedImageId)) {
4624
- this.focusedImageId = null;
4625
- this.isImageSelectionActive = false;
4706
+ this.setImageFocus(null, {
4707
+ syncCanvasSelection: false,
4708
+ skipRender: true
4709
+ });
4626
4710
  }
4627
4711
  this.getImageObjects().forEach((obj) => {
4628
4712
  var _a, _b;
@@ -4665,8 +4749,10 @@ var ImageTool = class {
4665
4749
  next[index] = this.normalizeItem({ ...next[index], ...updates });
4666
4750
  this.workingItems = next;
4667
4751
  this.hasWorkingChanges = true;
4668
- this.isImageSelectionActive = true;
4669
- this.focusedImageId = id;
4752
+ this.setImageFocus(id, {
4753
+ syncCanvasSelection: false,
4754
+ skipRender: true
4755
+ });
4670
4756
  if (this.isToolActive) {
4671
4757
  this.updateImages();
4672
4758
  }
@@ -4695,16 +4781,13 @@ var ImageTool = class {
4695
4781
  });
4696
4782
  this.updateConfig(next);
4697
4783
  if (replacingSource) {
4698
- this.focusedImageId = id;
4699
- this.isImageSelectionActive = true;
4700
- this.suppressSelectionClearUntil = Date.now() + IMAGE_REPLACE_GUARD_MS;
4701
4784
  this.debug("replace:image:begin", { id, replacingUrl });
4702
4785
  this.purgeSourceSizeCacheForItem(base);
4703
4786
  const loaded = await this.waitImageLoaded(id, true);
4704
4787
  this.debug("replace:image:loaded", { id, loaded });
4705
4788
  if (loaded) {
4706
4789
  await this.refitImageToFrame(id);
4707
- this.focusImageSelection(id);
4790
+ this.setImageFocus(id);
4708
4791
  }
4709
4792
  }
4710
4793
  }
@@ -4748,29 +4831,9 @@ var ImageTool = class {
4748
4831
  this.updateConfig(next);
4749
4832
  this.workingItems = this.cloneItems(next);
4750
4833
  this.hasWorkingChanges = false;
4751
- this.isImageSelectionActive = true;
4752
- this.focusedImageId = id;
4753
4834
  this.updateImages();
4754
4835
  this.emitWorkingChange(id);
4755
4836
  }
4756
- focusImageSelection(id) {
4757
- if (!this.canvasService) return;
4758
- const obj = this.getImageObject(id);
4759
- if (!obj) return;
4760
- this.isImageSelectionActive = true;
4761
- this.focusedImageId = id;
4762
- this.suppressSelectionClearUntil = Date.now() + 700;
4763
- obj.set({
4764
- selectable: true,
4765
- evented: true,
4766
- hasControls: true,
4767
- hasBorders: true
4768
- });
4769
- this.canvasService.canvas.setActiveObject(obj);
4770
- this.debug("focus:image", { id });
4771
- this.canvasService.requestRenderAll();
4772
- this.updateImages();
4773
- }
4774
4837
  async fitImageToArea(id, area) {
4775
4838
  var _a, _b;
4776
4839
  if (!this.canvasService) return;
@@ -4820,7 +4883,6 @@ var ImageTool = class {
4820
4883
  if (!frame.width || !frame.height) {
4821
4884
  return { ok: false, reason: "frame-not-ready" };
4822
4885
  }
4823
- const focusId = this.resolveReplaceTargetId(this.focusedImageId) || (this.workingItems.length === 1 ? this.workingItems[0].id : null);
4824
4886
  const next = [];
4825
4887
  for (const item of this.workingItems) {
4826
4888
  const url = await this.exportCroppedImageByIds([item.id], {
@@ -4844,13 +4906,7 @@ var ImageTool = class {
4844
4906
  this.hasWorkingChanges = false;
4845
4907
  this.workingItems = this.cloneItems(next);
4846
4908
  this.updateConfig(next);
4847
- this.emitWorkingChange(focusId);
4848
- if (focusId) {
4849
- this.focusedImageId = focusId;
4850
- this.isImageSelectionActive = true;
4851
- this.suppressSelectionClearUntil = Date.now() + IMAGE_REPLACE_GUARD_MS;
4852
- this.focusImageSelection(focusId);
4853
- }
4909
+ this.emitWorkingChange(this.focusedImageId);
4854
4910
  return { ok: true };
4855
4911
  }
4856
4912
  async exportCroppedImageByIds(imageIds, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pooder/kit",
3
- "version": "5.0.2",
3
+ "version": "5.0.4",
4
4
  "description": "Standard plugins for Pooder editor",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",