@optionfactory/ful 1.0.1 → 1.0.3

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/ful.mjs CHANGED
@@ -490,6 +490,7 @@ class HttpRequestBuilder {
490
490
  param(k, ...vs) {
491
491
  if (vs.length === 0 || vs[0] === null || vs[0] === undefined) {
492
492
  this.#params.delete(k);
493
+ return this;
493
494
  }
494
495
  for (const v of vs) {
495
496
  this.#params.append(k, v);
@@ -948,6 +949,65 @@ class AuthorizationCodeFlowInterceptor {
948
949
  }
949
950
  }
950
951
 
952
+ class AsyncEvents {
953
+ static async fireAsync(el, evt) {
954
+ el.dispatchEvent(evt);
955
+ return await evt.async?.promise;
956
+ }
957
+ /**
958
+ *
959
+ * @param {*} el
960
+ * @param {*} type
961
+ * @param {*} fn returning the result
962
+ * @param {*} options
963
+ * @returns
964
+ */
965
+ static asyncOn(el, type, fn, options) {
966
+ const listener = async (event) => {
967
+ let resolve, reject;
968
+ const promise = new Promise((res, rej) => {
969
+ resolve = res;
970
+ reject = rej;
971
+ });
972
+ event.async = { promise };
973
+ try {
974
+ //@ts-ignore
975
+ resolve(await fn(event));
976
+ } catch (e) {
977
+ //@ts-ignore
978
+ reject(e);
979
+ }
980
+ };
981
+ el.addEventListener(type, listener, options);
982
+ return listener;
983
+ }
984
+ /**
985
+ *
986
+ * @param {*} el
987
+ * @param {*} type
988
+ * @param {*} listener the listener returned by asyncOn
989
+ * @param {*} options
990
+ */
991
+ static asyncOff(el, type, listener, options) {
992
+ el.removeEventListener(type, listener, options);
993
+ }
994
+ static mixInto(...classes) {
995
+ for (const k of classes) {
996
+ Object.assign(k.prototype, {
997
+ async fireAsync(evt) {
998
+ return await AsyncEvents.fireAsync(this, evt);
999
+ },
1000
+ asyncOn(type, fn, options) {
1001
+ return AsyncEvents.asyncOn(this, type, fn, options);
1002
+ },
1003
+ asyncOff(type, listener, options) {
1004
+ return AsyncEvents.asyncOff(this, type, listener, options);
1005
+ }
1006
+ });
1007
+ }
1008
+ }
1009
+ }
1010
+
951
1011
  const timing = {
952
1012
  sleep(ms) {
953
1013
  return new Promise(resolve => setTimeout(resolve, ms));
@@ -1242,8 +1302,8 @@ class LocalFormLoader {
1242
1302
  async prepare(values, form) {
1243
1303
  return await this.#requestMapper(values, form);
1244
1304
  }
1245
- async submit(values, form) {
1246
- return values;
1305
+ async submit(values, form, response) {
1306
+ return response;
1247
1307
  }
1248
1308
  async transform(response, form) {
1249
1309
  return await this.#responseMapper(response, form);
@@ -1285,13 +1345,17 @@ class Form extends ParsedElement {
1285
1345
  try {
1286
1346
  const loader = Loaders.fromAttributes(this, 'loaders:form');
1287
1347
  const values = this.values;
1288
- const request = await loader.prepare(values, this);
1289
- const se = new CustomEvent('submit', { bubbles: true, cancelable: true, detail: { values, request } });
1290
- if (!this.dispatchEvent(se)) {
1291
- return;
1292
- }
1348
+ let request = await loader.prepare(values, this);
1293
1349
  try {
1294
- const response = await loader.submit(se.detail.request, this);
1350
+ const se = new CustomEvent('submit', { bubbles: true, cancelable: true, detail: { values, request } });
1351
+ if (!this.dispatchEvent(se)) {
1352
+ return;
1353
+ }
1354
+ const sre = new CustomEvent('submit:requested', { bubbles: true, cancelable: false, detail: { values: se.detail.values, request: se.detail.request} });
1355
+ let response = await AsyncEvents.fireAsync(this, sre);
1356
+ request = sre.detail.request;
1357
+
1358
+ response = await loader.submit(request, this, response);
1295
1359
  const mapped = await loader.transform(response, this);
1296
1360
  this.dispatchEvent(new CustomEvent('submit:success', { bubbles: true, cancelable: false, detail: { values, request, response: mapped } }));
1297
1361
  } catch (e) {
@@ -1299,12 +1363,13 @@ class Form extends ParsedElement {
1299
1363
  if (e instanceof Failure) {
1300
1364
  this.errors = e.problems;
1301
1365
  }
1302
- throw e;
1366
+ console.warn("failed to submit form", this, "reason:", e);
1303
1367
  }
1304
1368
  } finally {
1305
1369
  this.spinner(false);
1306
1370
  }
1307
1371
  }
1372
+
1308
1373
  spinner(spin) {
1309
1374
  this.querySelectorAll('ful-spinner').forEach(el => {
1310
1375
  const hel = /** @type HTMLElement */ (el);
@@ -2577,5 +2642,5 @@ class Plugin {
2577
2642
  }
2578
2643
  }
2579
2644
 
2580
- export { AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, Bindings, Checkbox, Dropdown, Failure, Form, FormLoader, Hex, HttpClient, HttpClientError, Input, InstantFilter, Loaders, LocalDateFilter, LocalStorage, MediaType, Pagination, Plugin, RadioGroup, Select, SelectLoader, SessionStorage, SortButton, Spinner, Table, TableSchemaParser, TextFilter, VersionedStorage, timing };
2645
+ export { AsyncEvents, AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, Bindings, Checkbox, Dropdown, Failure, Form, FormLoader, Hex, HttpClient, HttpClientError, Input, InstantFilter, Loaders, LocalDateFilter, LocalStorage, MediaType, Pagination, Plugin, RadioGroup, Select, SelectLoader, SessionStorage, SortButton, Spinner, Table, TableSchemaParser, TextFilter, VersionedStorage, timing };
2581
2646
  //# sourceMappingURL=ful.mjs.map