formeo 5.0.0 → 5.0.1

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.
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
3
  formeo - https://formeo.io
4
- Version: 4.2.5
4
+ Version: 5.0.0
5
5
  Author: Draggable https://draggable.io
6
6
  */
7
7
 
@@ -436,7 +436,7 @@ Author: Draggable https://draggable.io
436
436
  window.SmartTooltip = SmartTooltip;
437
437
  }
438
438
  const name$1 = "formeo";
439
- const version$2 = "4.2.5";
439
+ const version$2 = "5.0.0";
440
440
  const pkg = {
441
441
  name: name$1,
442
442
  version: version$2
@@ -10718,11 +10718,25 @@ Author: Draggable https://draggable.io
10718
10718
  const Fields = fields;
10719
10719
  const Controls = Controls$2;
10720
10720
  const getFormData = (formData, useSessionStorage = false) => {
10721
- if (formData) {
10722
- return clone$1(parseData(formData));
10721
+ if (formData !== void 0 && formData !== null) {
10722
+ const parsed = parseData(formData);
10723
+ if (parsed && typeof parsed === "object") {
10724
+ const cloned = clone$1(parsed);
10725
+ return {
10726
+ id: cloned.id || DEFAULT_FORMDATA().id,
10727
+ stages: cloned.stages || DEFAULT_FORMDATA().stages,
10728
+ rows: cloned.rows || {},
10729
+ columns: cloned.columns || {},
10730
+ fields: cloned.fields || {}
10731
+ };
10732
+ }
10733
+ console.warn("Formeo: Invalid formData provided, using default");
10723
10734
  }
10724
10735
  if (useSessionStorage) {
10725
- return sessionStorage.get(SESSION_FORMDATA_KEY) || DEFAULT_FORMDATA();
10736
+ const sessionData = sessionStorage.get(SESSION_FORMDATA_KEY);
10737
+ if (sessionData) {
10738
+ return sessionData;
10739
+ }
10726
10740
  }
10727
10741
  return DEFAULT_FORMDATA();
10728
10742
  };
@@ -11126,7 +11140,18 @@ Author: Draggable https://draggable.io
11126
11140
  };
11127
11141
  }
11128
11142
  };
11143
+ const INIT_STATES = {
11144
+ CREATED: "created",
11145
+ LOADING_RESOURCES: "loading",
11146
+ INITIALIZING: "initializing",
11147
+ READY: "ready",
11148
+ ERROR: "error"
11149
+ };
11129
11150
  let FormeoEditor$1 = class FormeoEditor {
11151
+ #initState = INIT_STATES.CREATED;
11152
+ #initPromise = null;
11153
+ #lockedFormData = null;
11154
+ #dataLoadedOnce = false;
11130
11155
  /**
11131
11156
  * @param {Object} options formeo options
11132
11157
  * @param {String|Object} userFormData loaded formData
@@ -11141,7 +11166,9 @@ Author: Draggable https://draggable.io
11141
11166
  this.opts = opts;
11142
11167
  dom.setOptions = opts;
11143
11168
  components.config = config;
11144
- this.userFormData = userFormData || formData;
11169
+ const providedData = userFormData || formData;
11170
+ this.#lockedFormData = providedData ? cleanFormData(providedData) : null;
11171
+ this.userFormData = this.#lockedFormData;
11145
11172
  this.Components = components;
11146
11173
  this.dom = dom;
11147
11174
  events.init({ debug, ...events$1 });
@@ -11156,7 +11183,9 @@ Author: Draggable https://draggable.io
11156
11183
  return this.Components.formData;
11157
11184
  }
11158
11185
  set formData(data = {}) {
11159
- this.userFormData = cleanFormData(data);
11186
+ const cleaned = cleanFormData(data);
11187
+ this.#lockedFormData = cleaned;
11188
+ this.userFormData = cleaned;
11160
11189
  this.load(this.userFormData, this.opts);
11161
11190
  }
11162
11191
  loadData(data = {}) {
@@ -11170,7 +11199,9 @@ Author: Draggable https://draggable.io
11170
11199
  * @return {void}
11171
11200
  */
11172
11201
  clear() {
11173
- this.userFormData = DEFAULT_FORMDATA();
11202
+ const defaultData = DEFAULT_FORMDATA();
11203
+ this.#lockedFormData = defaultData;
11204
+ this.userFormData = defaultData;
11174
11205
  this.Components.load(this.userFormData, this.opts);
11175
11206
  this.render();
11176
11207
  }
@@ -11180,6 +11211,7 @@ Author: Draggable https://draggable.io
11180
11211
  */
11181
11212
  async loadResources() {
11182
11213
  document.removeEventListener("DOMContentLoaded", this.loadResources);
11214
+ this.#initState = INIT_STATES.LOADING_RESOURCES;
11183
11215
  const promises = [
11184
11216
  fetchIcons(this.opts.svgSprite),
11185
11217
  fetchFormeoStyle(this.opts.style),
@@ -11189,38 +11221,142 @@ Author: Draggable https://draggable.io
11189
11221
  locale: globalThis.sessionStorage?.getItem(SESSION_LOCALE_KEY)
11190
11222
  })
11191
11223
  ].filter(Boolean);
11192
- await Promise.all(promises);
11193
- if (this.opts.allowEdit) {
11194
- this.init();
11224
+ try {
11225
+ await Promise.all(promises);
11226
+ if (this.opts.allowEdit) {
11227
+ this.init();
11228
+ }
11229
+ } catch (error) {
11230
+ this.#initState = INIT_STATES.ERROR;
11231
+ console.error("Failed to load resources:", error);
11232
+ throw error;
11195
11233
  }
11196
11234
  }
11197
11235
  /**
11198
11236
  * Formeo initializer
11199
- * @return {Object} References to formeo instance,
11237
+ * @return {Promise} References to formeo instance,
11200
11238
  * dom elements, actions events and more.
11201
11239
  */
11202
11240
  init() {
11203
- return Controls$2.init(this.opts.controls, this.opts.stickyControls).then((controls) => {
11241
+ if (this.#initState === INIT_STATES.INITIALIZING) {
11242
+ return this.#initPromise;
11243
+ }
11244
+ if (this.#initState === INIT_STATES.READY) {
11245
+ return this.#refreshUI();
11246
+ }
11247
+ this.#initState = INIT_STATES.INITIALIZING;
11248
+ this.#initPromise = Controls$2.init(this.opts.controls, this.opts.stickyControls).then((controls) => {
11204
11249
  this.controls = controls;
11205
- this.load(this.userFormData, this.opts);
11250
+ if (!this.#dataLoadedOnce) {
11251
+ this.#loadInitialData();
11252
+ this.#dataLoadedOnce = true;
11253
+ }
11206
11254
  this.formId = components.get("id");
11207
11255
  this.i18n = {
11208
- setLang: (formeoLocale) => {
11209
- globalThis.sessionStorage?.setItem(SESSION_LOCALE_KEY, formeoLocale);
11210
- const loadLang = mi18n.setCurrent(formeoLocale);
11211
- loadLang.then(() => {
11212
- this.init();
11213
- }, console.error);
11214
- }
11256
+ setLang: this.#setLanguage.bind(this)
11215
11257
  };
11258
+ this.render();
11259
+ this.#initState = INIT_STATES.READY;
11216
11260
  this.opts.onLoad?.(this);
11217
11261
  this.tooltipInstance = new SmartTooltip();
11262
+ return this;
11263
+ }).catch((error) => {
11264
+ this.#initState = INIT_STATES.ERROR;
11265
+ console.error("Failed to initialize editor:", error);
11266
+ throw error;
11218
11267
  });
11268
+ return this.#initPromise;
11269
+ }
11270
+ /**
11271
+ * Set language without reloading form data (fixes race condition)
11272
+ * @param {string} formeoLocale - locale code
11273
+ * @return {Promise}
11274
+ */
11275
+ async #setLanguage(formeoLocale) {
11276
+ globalThis.sessionStorage?.setItem(SESSION_LOCALE_KEY, formeoLocale);
11277
+ await mi18n.setCurrent(formeoLocale);
11278
+ await this.#refreshUI();
11279
+ }
11280
+ /**
11281
+ * Refresh UI without reloading data (used for language changes)
11282
+ * @return {Promise}
11283
+ */
11284
+ async #refreshUI() {
11285
+ this.controls = await Controls$2.init(this.opts.controls, this.opts.stickyControls);
11286
+ this.render();
11287
+ return this;
11288
+ }
11289
+ /**
11290
+ * Load initial data with proper priority
11291
+ */
11292
+ #loadInitialData() {
11293
+ const dataToLoad = this.#getDataWithPriority();
11294
+ this.Components.load(dataToLoad, this.opts);
11295
+ }
11296
+ /**
11297
+ * Get form data with proper priority:
11298
+ * 1. User-provided data (locked at construction)
11299
+ * 2. SessionStorage (if enabled)
11300
+ * 3. Default empty form
11301
+ * @return {Object} form data to load
11302
+ */
11303
+ #getDataWithPriority() {
11304
+ if (this.#lockedFormData) {
11305
+ return clone$1(this.#lockedFormData);
11306
+ }
11307
+ if (this.opts.sessionStorage) {
11308
+ const sessionData = sessionStorage.get(SESSION_FORMDATA_KEY);
11309
+ if (sessionData) {
11310
+ return sessionData;
11311
+ }
11312
+ }
11313
+ return DEFAULT_FORMDATA();
11219
11314
  }
11220
11315
  load(formData = this.userFormData, opts = this.opts) {
11221
11316
  this.Components.load(formData, opts);
11222
11317
  this.render();
11223
11318
  }
11319
+ /**
11320
+ * Get current initialization state
11321
+ * @return {string} current state
11322
+ */
11323
+ get initState() {
11324
+ return this.#initState;
11325
+ }
11326
+ /**
11327
+ * Check if the editor is ready
11328
+ * @return {boolean}
11329
+ */
11330
+ get isReady() {
11331
+ return this.#initState === INIT_STATES.READY;
11332
+ }
11333
+ /**
11334
+ * Wait for the editor to be ready
11335
+ * @return {Promise} resolves when editor is ready
11336
+ */
11337
+ async whenReady() {
11338
+ if (this.#initState === INIT_STATES.READY) {
11339
+ return this;
11340
+ }
11341
+ if (this.#initState === INIT_STATES.ERROR) {
11342
+ return Promise.reject(new Error("Editor initialization failed"));
11343
+ }
11344
+ if (this.#initPromise) {
11345
+ return this.#initPromise;
11346
+ }
11347
+ return new Promise((resolve, reject) => {
11348
+ const checkReady = () => {
11349
+ if (this.#initState === INIT_STATES.READY) {
11350
+ resolve(this);
11351
+ } else if (this.#initState === INIT_STATES.ERROR) {
11352
+ reject(new Error("Editor initialization failed"));
11353
+ } else {
11354
+ globalThis.requestAnimationFrame(checkReady);
11355
+ }
11356
+ };
11357
+ checkReady();
11358
+ });
11359
+ }
11224
11360
  /**
11225
11361
  * Render the formeo sections
11226
11362
  * @return {void}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "formeo",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "type": "module",
5
5
  "main": "dist/formeo.cjs.js",
6
6
  "module": "dist/formeo.es.js",
@@ -108,14 +108,14 @@
108
108
  "@semantic-release/changelog": "^6.0.3",
109
109
  "@semantic-release/git": "^10.0.1",
110
110
  "@semantic-release/github": "^11.0.1",
111
- "@semantic-release/npm": "^12.0.1",
111
+ "@semantic-release/npm": "^13.1.3",
112
112
  "@types/node": "^22.10.7",
113
113
  "ace-builds": "^1.36.5",
114
114
  "jsdom": "^25.0.1",
115
115
  "lefthook": "^1.7.18",
116
116
  "npm-run-all": "^2.1.0",
117
117
  "sass-embedded": "^1.80.1",
118
- "semantic-release": "^24.1.2",
118
+ "semantic-release": "^25.0.2",
119
119
  "svg-sprite": "^2.0.4",
120
120
  "vite": "^7.2.0",
121
121
  "vite-plugin-banner": "^0.8.0",