native-document 1.0.53 → 1.0.54

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,10 +1,10 @@
1
1
  var NativeDocument = (function (exports) {
2
2
  'use strict';
3
3
 
4
- let DebugManager = {};
4
+ let DebugManager$1 = {};
5
5
 
6
6
  {
7
- DebugManager = {
7
+ DebugManager$1 = {
8
8
  enabled: false,
9
9
 
10
10
  enable() {
@@ -35,7 +35,7 @@ var NativeDocument = (function (exports) {
35
35
  };
36
36
 
37
37
  }
38
- var DebugManager$1 = DebugManager;
38
+ var DebugManager = DebugManager$1;
39
39
 
40
40
  const MemoryManager = (function() {
41
41
 
@@ -84,7 +84,7 @@ var NativeDocument = (function (exports) {
84
84
  }
85
85
  }
86
86
  if (cleanedCount > 0) {
87
- DebugManager$1.log('Memory Auto Clean', `🧹 Cleaned ${cleanedCount} orphaned observables`);
87
+ DebugManager.log('Memory Auto Clean', `🧹 Cleaned ${cleanedCount} orphaned observables`);
88
88
  }
89
89
  }
90
90
  };
@@ -207,7 +207,7 @@ var NativeDocument = (function (exports) {
207
207
  try{
208
208
  callback.call(plugin, ...data);
209
209
  } catch (error) {
210
- DebugManager$1.error('Plugin Manager', `Error in plugin ${plugin.$name} for event ${eventName}`, error);
210
+ DebugManager.error('Plugin Manager', `Error in plugin ${plugin.$name} for event ${eventName}`, error);
211
211
  }
212
212
  }
213
213
  }
@@ -238,12 +238,68 @@ var NativeDocument = (function (exports) {
238
238
  return this.$observer.$currentValue === this.$target;
239
239
  };
240
240
 
241
+ /**
242
+ *
243
+ * @param {*} item
244
+ * @param {string|null} defaultKey
245
+ * @param {?Function} key
246
+ * @returns {*}
247
+ */
248
+ const getKey = (item, defaultKey, key) => {
249
+ if(Validator.isFunction(key)) return key(item, defaultKey);
250
+ if(Validator.isObservable(item)) {
251
+ const val = item.val();
252
+ return (val && key) ? val[key] : defaultKey;
253
+ }
254
+ if(!Validator.isObject(item)) {
255
+ return item;
256
+ }
257
+ return item[key]?.val?.() ?? item[key] ?? defaultKey;
258
+ };
259
+
260
+ const trim = function(str, char) {
261
+ return str.replace(new RegExp(`^[${char}]+|[${char}]+$`, 'g'), '');
262
+ };
263
+
264
+ const deepClone = (value, onObservableFound) => {
265
+ // Primitives
266
+ if (value === null || typeof value !== 'object') {
267
+ return value;
268
+ }
269
+
270
+ // Dates
271
+ if (value instanceof Date) {
272
+ return new Date(value.getTime());
273
+ }
274
+
275
+ // Arrays
276
+ if (Array.isArray(value)) {
277
+ return value.map(item => deepClone(item));
278
+ }
279
+
280
+ // Observables - keep the référence
281
+ if (Validator.isObservable(value)) {
282
+ onObservableFound && onObservableFound(value);
283
+ return value;
284
+ }
285
+
286
+ // Objects
287
+ const cloned = {};
288
+ for (const key in value) {
289
+ if (value.hasOwnProperty(key)) {
290
+ cloned[key] = deepClone(value[key]);
291
+ }
292
+ }
293
+ return cloned;
294
+ };
295
+
241
296
  /**
242
297
  *
243
298
  * @param {*} value
299
+ * @param {{ propagation: boolean, reset: boolean} | null} configs
244
300
  * @class ObservableItem
245
301
  */
246
- function ObservableItem(value) {
302
+ function ObservableItem(value, configs = null) {
247
303
  this.$previousValue = null;
248
304
  this.$currentValue = value;
249
305
  this.$isCleanedUp = false;
@@ -252,6 +308,14 @@ var NativeDocument = (function (exports) {
252
308
  this.$watchers = null;
253
309
 
254
310
  this.$memoryId = null;
311
+
312
+ if(configs) {
313
+ this.configs = configs;
314
+ if(configs.reset) {
315
+ this.$initialValue = Validator.isObject(value) ? deepClone(value) : value;
316
+ }
317
+ }
318
+
255
319
  PluginsManager.emit('CreateObservable', this);
256
320
  }
257
321
 
@@ -395,7 +459,7 @@ var NativeDocument = (function (exports) {
395
459
  ObservableItem.prototype.subscribe = function(callback, target = null) {
396
460
  this.$listeners = this.$listeners ?? [];
397
461
  if (this.$isCleanedUp) {
398
- DebugManager$1.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
462
+ DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
399
463
  return () => {};
400
464
  }
401
465
  if (typeof callback !== 'function') {
@@ -493,27 +557,16 @@ var NativeDocument = (function (exports) {
493
557
  this.set(!this.$currentValue);
494
558
  };
495
559
 
496
- /**
497
- *
498
- * @param {*} item
499
- * @param {string|null} defaultKey
500
- * @param {?Function} key
501
- * @returns {*}
502
- */
503
- const getKey = (item, defaultKey, key) => {
504
- if(Validator.isFunction(key)) return key(item, defaultKey);
505
- if(Validator.isObservable(item)) {
506
- const val = item.val();
507
- return (val && key) ? val[key] : defaultKey;
508
- }
509
- if(!Validator.isObject(item)) {
510
- return item;
560
+ ObservableItem.prototype.reset = function() {
561
+ if(!this.configs?.reset) {
562
+ return;
511
563
  }
512
- return item[key]?.val?.() ?? item[key] ?? defaultKey;
513
- };
514
-
515
- const trim = function(str, char) {
516
- return str.replace(new RegExp(`^[${char}]+|[${char}]+$`, 'g'), '');
564
+ const resetValue = (Validator.isObject(this.$initialValue))
565
+ ? deepClone(this.$initialValue, (observable) => {
566
+ observable.reset();
567
+ })
568
+ : this.$initialValue;
569
+ this.set(resetValue);
517
570
  };
518
571
 
519
572
  const DocumentObserver = {
@@ -690,6 +743,11 @@ var NativeDocument = (function (exports) {
690
743
  return this;
691
744
  };
692
745
 
746
+ NDElement.prototype.refSelf = function(target, name) {
747
+ target[name] = this;
748
+ return this;
749
+ };
750
+
693
751
  NDElement.prototype.unmountChildren = function() {
694
752
  let element = this.$element;
695
753
  for(let i = 0, length = element.children.length; i < length; i++) {
@@ -882,6 +940,80 @@ var NativeDocument = (function (exports) {
882
940
  };
883
941
  }
884
942
 
943
+ NDElement.prototype.with = function(methods) {
944
+ if (!methods || typeof methods !== 'object') {
945
+ throw new NativeDocumentError('extend() requires an object of methods');
946
+ }
947
+ {
948
+ if (!this.$localExtensions) {
949
+ this.$localExtensions = new Map();
950
+ }
951
+ }
952
+
953
+ for (const name in methods) {
954
+ const method = methods[name];
955
+
956
+ if (typeof method !== 'function') {
957
+ console.warn(`⚠️ extends(): "${name}" is not a function, skipping`);
958
+ continue;
959
+ }
960
+ {
961
+ if (this[name] && !this.$localExtensions.has(name)) {
962
+ DebugManager.warn('NDElement.extend', `Method "${name}" already exists and will be overwritten`);
963
+ }
964
+ this.$localExtensions.set(name, method);
965
+ }
966
+
967
+ this[name] = method.bind(this);
968
+ }
969
+
970
+ return this;
971
+ };
972
+
973
+ NDElement.extend = function(methods) {
974
+ if (!methods || typeof methods !== 'object') {
975
+ throw new NativeDocumentError('NDElement.extend() requires an object of methods');
976
+ }
977
+
978
+ if (Array.isArray(methods)) {
979
+ throw new NativeDocumentError('NDElement.extend() requires an object, not an array');
980
+ }
981
+
982
+ const protectedMethods = new Set([
983
+ 'constructor', 'valueOf', '$element', '$observer',
984
+ 'ref', 'remove', 'cleanup', 'with', 'extend', 'attach',
985
+ 'lifecycle', 'mounted', 'unmounted', 'unmountChildren'
986
+ ]);
987
+
988
+ for (const name in methods) {
989
+ if (!methods.hasOwnProperty(name)) {
990
+ continue;
991
+ }
992
+
993
+ const method = methods[name];
994
+
995
+ if (typeof method !== 'function') {
996
+ DebugManager.warn('NDElement.extend', `"${name}" is not a function, skipping`);
997
+ continue;
998
+ }
999
+
1000
+ if (protectedMethods.has(name)) {
1001
+ DebugManager.error('NDElement.extend', `Cannot override protected method "${name}"`);
1002
+ throw new NativeDocumentError(`Cannot override protected method "${name}"`);
1003
+ }
1004
+
1005
+ if (NDElement.prototype[name]) {
1006
+ DebugManager.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
1007
+ }
1008
+
1009
+ NDElement.prototype[name] = method;
1010
+ }
1011
+
1012
+ PluginsManager.emit('NDElementExtended', methods);
1013
+
1014
+ return NDElement;
1015
+ };
1016
+
885
1017
  const COMMON_NODE_TYPES = {
886
1018
  ELEMENT: 1,
887
1019
  TEXT: 3,
@@ -927,7 +1059,7 @@ var NativeDocument = (function (exports) {
927
1059
  return typeof value === 'function' && value.constructor.name === 'AsyncFunction';
928
1060
  },
929
1061
  isObject(value) {
930
- return typeof value === 'object';
1062
+ return typeof value === 'object' && value !== null;
931
1063
  },
932
1064
  isJson(value) {
933
1065
  return typeof value === 'object' && value !== null && !Array.isArray(value) && value.constructor.name === 'Object';
@@ -1017,7 +1149,7 @@ var NativeDocument = (function (exports) {
1017
1149
  const foundReserved = Object.keys(attributes).filter(key => reserved.includes(key));
1018
1150
 
1019
1151
  if (foundReserved.length > 0) {
1020
- DebugManager$1.warn('Validator', `Reserved attributes found: ${foundReserved.join(', ')}`);
1152
+ DebugManager.warn('Validator', `Reserved attributes found: ${foundReserved.join(', ')}`);
1021
1153
  }
1022
1154
 
1023
1155
  return attributes;
@@ -1065,7 +1197,7 @@ var NativeDocument = (function (exports) {
1065
1197
  element.appendChild = function(child, before = null) {
1066
1198
  const parent = anchorEnd.parentNode;
1067
1199
  if(!parent) {
1068
- DebugManager$1.error('Anchor', 'Anchor : parent not found', child);
1200
+ DebugManager.error('Anchor', 'Anchor : parent not found', child);
1069
1201
  return;
1070
1202
  }
1071
1203
  before = before ?? anchorEnd;
@@ -1176,11 +1308,12 @@ var NativeDocument = (function (exports) {
1176
1308
  /**
1177
1309
  *
1178
1310
  * @param {*} value
1311
+ * @param {{ propagation: boolean, reset: boolean} | null} configs
1179
1312
  * @returns {ObservableItem}
1180
1313
  * @constructor
1181
1314
  */
1182
- function Observable(value) {
1183
- return new ObservableItem(value);
1315
+ function Observable(value, configs = null) {
1316
+ return new ObservableItem(value, configs);
1184
1317
  }
1185
1318
 
1186
1319
  const $ = Observable;
@@ -1556,10 +1689,20 @@ var NativeDocument = (function (exports) {
1556
1689
  }
1557
1690
  };
1558
1691
 
1559
- Object.defineProperty(HTMLElement.prototype, 'nd', {
1692
+ const property = {
1560
1693
  configurable: true,
1561
1694
  get() {
1562
- return new NDElement(this);
1695
+ return new NDElement(this);
1696
+ }
1697
+ };
1698
+
1699
+ Object.defineProperty(HTMLElement.prototype, 'nd', property);
1700
+
1701
+ Object.defineProperty(DocumentFragment.prototype, 'nd', property);
1702
+ Object.defineProperty(NDElement.prototype, 'nd', {
1703
+ configurable: true,
1704
+ get: function() {
1705
+ return this;
1563
1706
  }
1564
1707
  });
1565
1708
 
@@ -2138,12 +2281,18 @@ var NativeDocument = (function (exports) {
2138
2281
  const noMutationMethods = ['map', 'forEach', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex', 'concat', 'includes', 'indexOf'];
2139
2282
 
2140
2283
 
2141
- const ObservableArray = function (target, { propagation = false, deep = false } = {}) {
2284
+ /**
2285
+ *
2286
+ * @param target
2287
+ * @param {{propagation: boolean, deep: boolean, reset: boolean}|null} configs
2288
+ * @constructor
2289
+ */
2290
+ const ObservableArray = function (target, configs) {
2142
2291
  if(!Array.isArray(target)) {
2143
2292
  throw new NativeDocumentError('Observable.array : target must be an array');
2144
2293
  }
2145
2294
 
2146
- ObservableItem.call(this, target);
2295
+ ObservableItem.call(this, target, configs);
2147
2296
  PluginsManager.emit('CreateObservableArray', this);
2148
2297
  };
2149
2298
 
@@ -2243,10 +2392,11 @@ var NativeDocument = (function (exports) {
2243
2392
  /**
2244
2393
  *
2245
2394
  * @param {Array} target
2395
+ * @param {{propagation: boolean, deep: boolean, reset: boolean}|null} configs
2246
2396
  * @returns {ObservableArray}
2247
2397
  */
2248
- Observable.array = function(target) {
2249
- return new ObservableArray(target);
2398
+ Observable.array = function(target, configs = null) {
2399
+ return new ObservableArray(target, configs);
2250
2400
  };
2251
2401
 
2252
2402
  /**
@@ -2310,40 +2460,47 @@ var NativeDocument = (function (exports) {
2310
2460
  /**
2311
2461
  *
2312
2462
  * @param {Object} initialValue
2313
- * @param {{propagation: boolean, deep: boolean}} configs
2463
+ * @param {{propagation: boolean, deep: boolean, reset: boolean}|null} configs
2314
2464
  * @returns {Proxy}
2315
2465
  */
2316
- Observable.init = function(initialValue, { propagation= false, deep = true } = {}) {
2466
+ Observable.init = function(initialValue, configs = null) {
2317
2467
  const data = {};
2318
2468
  for(const key in initialValue) {
2319
2469
  const itemValue = initialValue[key];
2320
2470
  if(Array.isArray(itemValue)) {
2321
- if(deep) {
2471
+ if(configs?.deep !== false) {
2322
2472
  const mappedItemValue = itemValue.map(item => {
2323
2473
  if(Validator.isJson(item)) {
2324
- return Observable.json(item, { propagation, deep });
2474
+ return Observable.json(item, configs);
2325
2475
  }
2326
2476
  if(Validator.isArray(item)) {
2327
- return Observable.array(item, { propagation, deep });
2477
+ return Observable.array(item, configs);
2328
2478
  }
2329
- return Observable(item);
2479
+ return Observable(item, configs);
2330
2480
  });
2331
- data[key] = Observable.array(mappedItemValue, { propagation });
2481
+ data[key] = Observable.array(mappedItemValue, configs);
2332
2482
  continue;
2333
2483
  }
2334
- data[key] = Observable.array(itemValue, { propagation });
2484
+ data[key] = Observable.array(itemValue, configs);
2335
2485
  continue;
2336
2486
  }
2337
2487
  if(Validator.isObservable(itemValue) || Validator.isProxy(itemValue)) {
2338
2488
  data[key] = itemValue;
2339
2489
  continue;
2340
2490
  }
2341
- data[key] = Observable(itemValue);
2491
+ data[key] = Observable(itemValue, configs);
2342
2492
  }
2343
2493
 
2494
+ const $reset = () => {
2495
+ for(const key in data) {
2496
+ const item = data[key];
2497
+ item.reset();
2498
+ }
2499
+ };
2500
+
2344
2501
  const $val = () => ObservableObjectValue(data);
2345
2502
 
2346
- const $clone = () => Observable.init($val(), { propagation, deep });
2503
+ const $clone = () => Observable.init($val(), configs);
2347
2504
 
2348
2505
  const $updateWith = (values) => {
2349
2506
  Observable.update(proxy, values);
@@ -2353,34 +2510,17 @@ var NativeDocument = (function (exports) {
2353
2510
 
2354
2511
  const proxy = new Proxy(data, {
2355
2512
  get(target, property) {
2356
- if(property === '__isProxy__') {
2357
- return true;
2358
- }
2359
- if(property === '$value') {
2360
- return $val();
2361
- }
2362
- if(property === '$clone') {
2363
- return $clone;
2364
- }
2365
- if(property === '$keys') {
2366
- return Object.keys(initialValue);
2367
- }
2368
- if(property === '$observables') {
2369
- return Object.values(target);
2370
- }
2371
- if(property === '$set' || property === '$updateWith') {
2372
- return $updateWith;
2373
- }
2374
- if(property === '$get') {
2375
- return $get;
2376
- }
2377
- if(property === '$val') {
2378
- return $val;
2379
- }
2380
- if(target[property] !== undefined) {
2381
- return target[property];
2382
- }
2383
- return undefined;
2513
+ if(property === '__isProxy__') { return true; }
2514
+ if(property === '$value') { return $val() }
2515
+ if(property === 'get' || property === '$get') { return $get; }
2516
+ if(property === 'val' || property === '$val') { return $val; }
2517
+ if(property === 'set' || property === '$set' || property === '$updateWith') { return $updateWith; }
2518
+ if(property === 'observables' || property === '$observables') { return Object.values(target); }
2519
+ if(property === 'keys'|| property === '$keys') { return Object.keys(initialValue); }
2520
+ if(property === 'clone' || property === '$clone') { return $clone; }
2521
+ if(property === 'reset') { return $reset; }
2522
+ if(property === 'configs') { return configs; }
2523
+ return target[property];
2384
2524
  },
2385
2525
  set(target, prop, newValue) {
2386
2526
  if(target[prop] !== undefined) {
@@ -2431,6 +2571,7 @@ var NativeDocument = (function (exports) {
2431
2571
 
2432
2572
  Observable.update = function($target, newData) {
2433
2573
  const data = Validator.isProxy(newData) ? newData.$value : newData;
2574
+ const configs = $target.configs;
2434
2575
 
2435
2576
  for(const key in data) {
2436
2577
  const targetItem = $target[key];
@@ -2443,9 +2584,9 @@ var NativeDocument = (function (exports) {
2443
2584
  if(Validator.isObservable(firstElementFromOriginalValue) || Validator.isProxy(firstElementFromOriginalValue)) {
2444
2585
  const newValues = newValue.map(item => {
2445
2586
  if(Validator.isProxy(firstElementFromOriginalValue)) {
2446
- return Observable.init(item);
2587
+ return Observable.init(item, configs);
2447
2588
  }
2448
- return Observable(item);
2589
+ return Observable(item, configs);
2449
2590
  });
2450
2591
  targetItem.set(newValues);
2451
2592
  continue;
@@ -2637,7 +2778,7 @@ var NativeDocument = (function (exports) {
2637
2778
  }
2638
2779
  cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
2639
2780
  } catch (e) {
2640
- DebugManager$1.error('ForEach', `Error creating element for key ${keyId}` , e);
2781
+ DebugManager.error('ForEach', `Error creating element for key ${keyId}` , e);
2641
2782
  throw e;
2642
2783
  }
2643
2784
  return keyId;
@@ -3009,7 +3150,7 @@ var NativeDocument = (function (exports) {
3009
3150
  */
3010
3151
  const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
3011
3152
  if(!(Validator.isObservable(condition)) && !Validator.isObservableWhenResult(condition)) {
3012
- return DebugManager$1.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
3153
+ return DebugManager.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
3013
3154
  }
3014
3155
  const element = new Anchor('Show if : '+(comment || ''));
3015
3156
 
@@ -3141,7 +3282,18 @@ var NativeDocument = (function (exports) {
3141
3282
  }
3142
3283
  });
3143
3284
 
3144
- return anchor;
3285
+ return anchor.nd.with({
3286
+ add(key, view, shouldFocusOn = false) {
3287
+ values[key] = view;
3288
+ if(shouldFocusOn) {
3289
+ $condition.set(key);
3290
+ }
3291
+ },
3292
+ remove(key) {
3293
+ shouldKeepInCache && cache.delete(key);
3294
+ delete values[key];
3295
+ }
3296
+ });
3145
3297
  };
3146
3298
 
3147
3299
 
@@ -3785,7 +3937,7 @@ var NativeDocument = (function (exports) {
3785
3937
  window.history.pushState({ name: route.name(), params, path}, route.name() || path , path);
3786
3938
  this.handleRouteChange(route, params, query, path);
3787
3939
  } catch (e) {
3788
- DebugManager$1.error('HistoryRouter', 'Error in pushState', e);
3940
+ DebugManager.error('HistoryRouter', 'Error in pushState', e);
3789
3941
  }
3790
3942
  };
3791
3943
  /**
@@ -3798,7 +3950,7 @@ var NativeDocument = (function (exports) {
3798
3950
  window.history.replaceState({ name: route.name(), params, path}, route.name() || path , path);
3799
3951
  this.handleRouteChange(route, params, {}, path);
3800
3952
  } catch(e) {
3801
- DebugManager$1.error('HistoryRouter', 'Error in replaceState', e);
3953
+ DebugManager.error('HistoryRouter', 'Error in replaceState', e);
3802
3954
  }
3803
3955
  };
3804
3956
  this.forward = function() {
@@ -3825,7 +3977,7 @@ var NativeDocument = (function (exports) {
3825
3977
  }
3826
3978
  this.handleRouteChange(route, params, query, path);
3827
3979
  } catch(e) {
3828
- DebugManager$1.error('HistoryRouter', 'Error in popstate event', e);
3980
+ DebugManager.error('HistoryRouter', 'Error in popstate event', e);
3829
3981
  }
3830
3982
  });
3831
3983
  const { route, params, query, path } = this.resolve(defaultPath || (window.location.pathname+window.location.search));
@@ -3979,7 +4131,7 @@ var NativeDocument = (function (exports) {
3979
4131
  listener(request);
3980
4132
  next && next(request);
3981
4133
  } catch (e) {
3982
- DebugManager$1.warn('Route Listener', 'Error in listener:', e);
4134
+ DebugManager.warn('Route Listener', 'Error in listener:', e);
3983
4135
  }
3984
4136
  }
3985
4137
  };
@@ -4138,7 +4290,7 @@ var NativeDocument = (function (exports) {
4138
4290
  */
4139
4291
  Router.create = function(options, callback) {
4140
4292
  if(!Validator.isFunction(callback)) {
4141
- DebugManager$1.error('Router', 'Callback must be a function', e);
4293
+ DebugManager.error('Router', 'Callback must be a function', e);
4142
4294
  throw new RouterError('Callback must be a function');
4143
4295
  }
4144
4296
  const router = new Router(options);
@@ -4218,6 +4370,104 @@ var NativeDocument = (function (exports) {
4218
4370
  Router: Router
4219
4371
  });
4220
4372
 
4373
+ function NativeFetch($baseUrl) {
4374
+
4375
+ const $interceptors = {
4376
+ request: [],
4377
+ response: []
4378
+ };
4379
+
4380
+ this.interceptors = {
4381
+ response: (callback) => {
4382
+ $interceptors.response.push(callback);
4383
+ },
4384
+ request: (callback) => {
4385
+ $interceptors.request.push(callback);
4386
+ }
4387
+ };
4388
+
4389
+ this.fetch = async function(method, endpoint, params = {}, options = {}) {
4390
+ if(options.formData) {
4391
+ const formData = new FormData();
4392
+ for(const key in params) {
4393
+ formData.append(key, params[key]);
4394
+ }
4395
+ params = formData;
4396
+ }
4397
+ if(!endpoint.startsWith('http')) {
4398
+ endpoint = ($baseUrl.endsWith('/') ? $baseUrl : $baseUrl+'/') + endpoint;
4399
+ }
4400
+ let configs = {
4401
+ method,
4402
+ headers: {
4403
+ ...(options.headers || {})
4404
+ },
4405
+ };
4406
+ if(params) {
4407
+ if(params instanceof FormData) {
4408
+ configs.body = params;
4409
+ }
4410
+ else {
4411
+ configs.headers['Content-Type'] = 'application/json';
4412
+ if(method !== 'GET') {
4413
+ configs.body = JSON.stringify(params);
4414
+ } else {
4415
+ configs.params = params;
4416
+ }
4417
+ }
4418
+ }
4419
+
4420
+ for(const interceptor of $interceptors.request) {
4421
+ configs = (await interceptor(configs, endpoint)) || configs;
4422
+ }
4423
+
4424
+ let response = await fetch(endpoint, configs);
4425
+
4426
+ for(const interceptor of $interceptors.response) {
4427
+ response = (await interceptor(response, endpoint)) || response;
4428
+ }
4429
+
4430
+ const contentType = response.headers.get('content-type') || '';
4431
+ const data = contentType.includes('application/json')
4432
+ ? await response.json()
4433
+ : await response.text();
4434
+
4435
+ if(!response.ok) {
4436
+ const error = new Error(data?.message || response.statusText);
4437
+ error.status = response.status;
4438
+ error.data = data;
4439
+ throw error;
4440
+ }
4441
+
4442
+ return data;
4443
+ };
4444
+
4445
+
4446
+ this.post = function (endpoint, params = {}, options = {}) {
4447
+ return this.fetch('POST', endpoint, params, options);
4448
+ };
4449
+ this.put = function (endpoint, params = {}, options = {}) {
4450
+ return this.fetch('PUT', endpoint, params, options);
4451
+ };
4452
+ this.delete = function (endpoint, params = {}, options = {}) {
4453
+ return this.fetch('DELETE', endpoint, params, options);
4454
+ };
4455
+ this.get = function (endpoint, params = {}, options = {}) {
4456
+ return this.fetch('GET', endpoint, params, options);
4457
+ };
4458
+ }
4459
+
4460
+ const Service = {
4461
+ once: fn => autoOnce(fn),
4462
+ memoize: fn => autoMemoize(fn)
4463
+ };
4464
+
4465
+ var utils = /*#__PURE__*/Object.freeze({
4466
+ __proto__: null,
4467
+ NativeFetch: NativeFetch,
4468
+ Service: Service
4469
+ });
4470
+
4221
4471
  exports.$ = $;
4222
4472
  exports.ElementCreator = ElementCreator;
4223
4473
  exports.HtmlElementWrapper = HtmlElementWrapper;
@@ -4241,6 +4491,7 @@ var NativeDocument = (function (exports) {
4241
4491
  exports.router = router;
4242
4492
  exports.useCache = useCache;
4243
4493
  exports.useSingleton = useSingleton;
4494
+ exports.utils = utils;
4244
4495
 
4245
4496
  return exports;
4246
4497