native-document 1.0.31 → 1.0.32

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.
@@ -309,6 +309,7 @@ var NativeDocument = (function (exports) {
309
309
  this.$currentValue = newValue;
310
310
  PluginsManager.emit('ObservableBeforeChange', this);
311
311
  this.trigger();
312
+ this.$previousValue = null;
312
313
  PluginsManager.emit('ObservableAfterChange', this);
313
314
  };
314
315
 
@@ -809,7 +810,7 @@ var NativeDocument = (function (exports) {
809
810
  }
810
811
  };
811
812
 
812
- function Anchor(name) {
813
+ function Anchor(name, isUniqueChild = false) {
813
814
  const element = document.createDocumentFragment();
814
815
 
815
816
  const anchorStart = document.createComment('Anchor Start : '+name);
@@ -822,14 +823,25 @@ var NativeDocument = (function (exports) {
822
823
  element.nativeAppendChild = element.appendChild;
823
824
 
824
825
  const insertBefore = function(parent, child, target) {
826
+ const element = Validator.isElement(child) ? child : ElementCreator.getChild(child);
825
827
  if(parent === element) {
826
- parent.nativeInsertBefore(ElementCreator.getChild(child), target);
828
+ parent.nativeInsertBefore(element, target);
829
+ return;
830
+ }
831
+ if(isUniqueChild || target === anchorEnd) {
832
+ parent.append(element, target);
827
833
  return;
828
834
  }
829
- parent.insertBefore(ElementCreator.getChild(child), target);
835
+ parent.insertBefore(element, target);
830
836
  };
831
837
 
832
838
  element.appendElement = function(child, before = null) {
839
+ if(isUniqueChild) {
840
+ (before && before !== anchorEnd)
841
+ ? anchorEnd.parentNode.insertBefore(child, anchorEnd)
842
+ : anchorEnd.parentNode.append(child, anchorEnd);
843
+ return;
844
+ }
833
845
  if(anchorEnd.parentNode === element) {
834
846
  anchorEnd.parentNode.nativeInsertBefore(child, before || anchorEnd);
835
847
  return;
@@ -844,14 +856,6 @@ var NativeDocument = (function (exports) {
844
856
  return;
845
857
  }
846
858
  before = before ?? anchorEnd;
847
- if(Validator.isArray(child)) {
848
- const fragment = document.createDocumentFragment();
849
- for(let i = 0, length = child.length; i < length; i++) {
850
- fragment.appendChild(ElementCreator.getChild(child[i]));
851
- }
852
- insertBefore(parent, fragment, before);
853
- return element;
854
- }
855
859
  insertBefore(parent, child, before);
856
860
  };
857
861
 
@@ -860,7 +864,7 @@ var NativeDocument = (function (exports) {
860
864
  if(parent === element) {
861
865
  return;
862
866
  }
863
- if(parent.firstChild === anchorStart && parent.lastChild === anchorEnd) {
867
+ if(isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd)) {
864
868
  parent.replaceChildren(anchorStart, anchorEnd);
865
869
  return;
866
870
  }
@@ -879,6 +883,10 @@ var NativeDocument = (function (exports) {
879
883
  if(parent === element) {
880
884
  return;
881
885
  }
886
+ if(isUniqueChild) {
887
+ parent.replaceChildren(anchorEnd, anchorEnd);
888
+ return;
889
+ }
882
890
  let itemToRemove = anchorStart.nextSibling, tempItem;
883
891
  while(itemToRemove !== anchorEnd) {
884
892
  tempItem = itemToRemove.nextSibling;
@@ -898,7 +906,7 @@ var NativeDocument = (function (exports) {
898
906
  if(!parent) {
899
907
  return;
900
908
  }
901
- if(parent.firstChild === anchorStart && parent.lastChild === anchorEnd) {
909
+ if(isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd)) {
902
910
  parent.replaceChildren(anchorStart, child, anchorEnd);
903
911
  return;
904
912
  }
@@ -1142,7 +1150,7 @@ var NativeDocument = (function (exports) {
1142
1150
  */
1143
1151
  createObservableNode(parent, observable) {
1144
1152
  const text = ElementCreator.createTextNode();
1145
- observable.subscribe(value => text.nodeValue = String(value));
1153
+ observable.subscribe(value => text.nodeValue = value);
1146
1154
  text.nodeValue = observable.val();
1147
1155
  parent && parent.appendChild(text);
1148
1156
  return text;
@@ -1156,7 +1164,7 @@ var NativeDocument = (function (exports) {
1156
1164
  */
1157
1165
  createStaticTextNode(parent, value) {
1158
1166
  let text = ElementCreator.createTextNode();
1159
- text.nodeValue = String(value);
1167
+ text.nodeValue = value;
1160
1168
  parent && parent.appendChild(text);
1161
1169
  return text;
1162
1170
  },
@@ -1270,6 +1278,9 @@ var NativeDocument = (function (exports) {
1270
1278
  }
1271
1279
  }
1272
1280
 
1281
+ exports.withValidation = (fn) => fn;
1282
+ exports.ArgTypes = {};
1283
+
1273
1284
  /**
1274
1285
  *
1275
1286
  * @type {{string: (function(*): {name: *, type: string, validate: function(*): boolean}),
@@ -1287,85 +1298,90 @@ var NativeDocument = (function (exports) {
1287
1298
  * validate: function(*): boolean})
1288
1299
  * }}
1289
1300
  */
1290
- const ArgTypes = {
1291
- string: (name) => ({ name, type: 'string', validate: (v) => Validator.isString(v) }),
1292
- number: (name) => ({ name, type: 'number', validate: (v) => Validator.isNumber(v) }),
1293
- boolean: (name) => ({ name, type: 'boolean', validate: (v) => Validator.isBoolean(v) }),
1294
- observable: (name) => ({ name, type: 'observable', validate: (v) => Validator.isObservable(v) }),
1295
- element: (name) => ({ name, type: 'element', validate: (v) => Validator.isElement(v) }),
1296
- function: (name) => ({ name, type: 'function', validate: (v) => Validator.isFunction(v) }),
1297
- object: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v)) }),
1298
- objectNotNull: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v) && v !== null) }),
1299
- children: (name) => ({ name, type: 'children', validate: (v) => Validator.validateChildren(v) }),
1300
- attributes: (name) => ({ name, type: 'attributes', validate: (v) => Validator.validateAttributes(v) }),
1301
-
1302
- // Optional arguments
1303
- optional: (argType) => ({ ...argType, optional: true }),
1304
-
1305
- // Union types
1306
- oneOf: (name, ...argTypes) => ({
1307
- name,
1308
- type: 'oneOf',
1309
- types: argTypes,
1310
- validate: (v) => argTypes.some(type => type.validate(v))
1311
- })
1312
- };
1301
+ {
1302
+ exports.ArgTypes = {
1303
+ string: (name) => ({ name, type: 'string', validate: (v) => Validator.isString(v) }),
1304
+ number: (name) => ({ name, type: 'number', validate: (v) => Validator.isNumber(v) }),
1305
+ boolean: (name) => ({ name, type: 'boolean', validate: (v) => Validator.isBoolean(v) }),
1306
+ observable: (name) => ({ name, type: 'observable', validate: (v) => Validator.isObservable(v) }),
1307
+ element: (name) => ({ name, type: 'element', validate: (v) => Validator.isElement(v) }),
1308
+ function: (name) => ({ name, type: 'function', validate: (v) => Validator.isFunction(v) }),
1309
+ object: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v)) }),
1310
+ objectNotNull: (name) => ({ name, type: 'object', validate: (v) => (Validator.isObject(v) && v !== null) }),
1311
+ children: (name) => ({ name, type: 'children', validate: (v) => Validator.validateChildren(v) }),
1312
+ attributes: (name) => ({ name, type: 'attributes', validate: (v) => Validator.validateAttributes(v) }),
1313
+
1314
+ // Optional arguments
1315
+ optional: (argType) => ({ ...argType, optional: true }),
1316
+
1317
+ // Union types
1318
+ oneOf: (name, ...argTypes) => ({
1319
+ name,
1320
+ type: 'oneOf',
1321
+ types: argTypes,
1322
+ validate: (v) => argTypes.some(type => type.validate(v))
1323
+ })
1324
+ };
1313
1325
 
1314
- /**
1315
- *
1316
- * @param {Array} args
1317
- * @param {Array} argSchema
1318
- * @param {string} fnName
1319
- */
1320
- const validateArgs = (args, argSchema, fnName = 'Function') => {
1321
- if (!argSchema) return;
1322
1326
 
1323
- const errors = [];
1327
+ /**
1328
+ *
1329
+ * @param {Array} args
1330
+ * @param {Array} argSchema
1331
+ * @param {string} fnName
1332
+ */
1333
+ const validateArgs = (args, argSchema, fnName = 'Function') => {
1334
+ if (!argSchema) return;
1324
1335
 
1325
- // Check the number of arguments
1326
- const requiredCount = argSchema.filter(arg => !arg.optional).length;
1327
- if (args.length < requiredCount) {
1328
- errors.push(`${fnName}: Expected at least ${requiredCount} arguments, got ${args.length}`);
1329
- }
1336
+ const errors = [];
1330
1337
 
1331
- // Validate each argument
1332
- argSchema.forEach((schema, index) => {
1333
- const position = index + 1;
1334
- const value = args[index];
1338
+ // Check the number of arguments
1339
+ const requiredCount = argSchema.filter(arg => !arg.optional).length;
1340
+ if (args.length < requiredCount) {
1341
+ errors.push(`${fnName}: Expected at least ${requiredCount} arguments, got ${args.length}`);
1342
+ }
1343
+
1344
+ // Validate each argument
1345
+ argSchema.forEach((schema, index) => {
1346
+ const position = index + 1;
1347
+ const value = args[index];
1348
+
1349
+ if (value === undefined) {
1350
+ if (!schema.optional) {
1351
+ errors.push(`${fnName}: Missing required argument '${schema.name}' at position ${position}`);
1352
+ }
1353
+ return;
1354
+ }
1335
1355
 
1336
- if (value === undefined) {
1337
- if (!schema.optional) {
1338
- errors.push(`${fnName}: Missing required argument '${schema.name}' at position ${position}`);
1356
+ if (!schema.validate(value)) {
1357
+ const valueTypeOf = value?.constructor?.name || typeof value;
1358
+ errors.push(`${fnName}: Invalid argument '${schema.name}' at position ${position}, expected ${schema.type}, got ${valueTypeOf}`);
1339
1359
  }
1340
- return;
1341
- }
1360
+ });
1342
1361
 
1343
- if (!schema.validate(value)) {
1344
- const valueTypeOf = value?.constructor?.name || typeof value;
1345
- errors.push(`${fnName}: Invalid argument '${schema.name}' at position ${position}, expected ${schema.type}, got ${valueTypeOf}`);
1362
+ if (errors.length > 0) {
1363
+ throw new ArgTypesError(`Argument validation failed`, errors);
1346
1364
  }
1347
- });
1365
+ };
1348
1366
 
1349
- if (errors.length > 0) {
1350
- throw new ArgTypesError(`Argument validation failed`, errors);
1351
- }
1352
- };
1353
1367
 
1354
- /**
1355
- * @param {Function} fn
1356
- * @param {Array} argSchema
1357
- * @param {string} fnName
1358
- * @returns {Function}
1359
- */
1360
- const withValidation = (fn, argSchema, fnName = 'Function') => {
1361
- if(!Validator.isArray(argSchema)) {
1362
- throw new NativeDocumentError('withValidation : argSchema must be an array');
1363
- }
1364
- return function(...args) {
1365
- validateArgs(args, argSchema, fn.name || fnName);
1366
- return fn.apply(this, args);
1368
+
1369
+ /**
1370
+ * @param {Function} fn
1371
+ * @param {Array} argSchema
1372
+ * @param {string} fnName
1373
+ * @returns {Function}
1374
+ */
1375
+ exports.withValidation = (fn, argSchema, fnName = 'Function') => {
1376
+ if(!Validator.isArray(argSchema)) {
1377
+ throw new NativeDocumentError('withValidation : argSchema must be an array');
1378
+ }
1379
+ return function(...args) {
1380
+ validateArgs(args, argSchema, fn.name || fnName);
1381
+ return fn.apply(this, args);
1382
+ };
1367
1383
  };
1368
- };
1384
+ }
1369
1385
 
1370
1386
  const normalizeComponentArgs = function(props, children = null) {
1371
1387
  if(!Validator.isJson(props)) {
@@ -1376,6 +1392,17 @@ var NativeDocument = (function (exports) {
1376
1392
  return { props, children };
1377
1393
  };
1378
1394
 
1395
+ function createHtmlElement($tagName, _attributes, _children = null, customWrapper) {
1396
+ const { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
1397
+ const element = ElementCreator.createElement($tagName);
1398
+ const finalElement = (typeof customWrapper === 'function') ? customWrapper(element) : element;
1399
+
1400
+ ElementCreator.processAttributes(finalElement, attributes);
1401
+ ElementCreator.processChildren(children, finalElement);
1402
+
1403
+ return ElementCreator.setup(finalElement, attributes, customWrapper);
1404
+ }
1405
+
1379
1406
  /**
1380
1407
  *
1381
1408
  * @param {string} name
@@ -1383,26 +1410,27 @@ var NativeDocument = (function (exports) {
1383
1410
  * @returns {Function}
1384
1411
  */
1385
1412
  function HtmlElementWrapper(name, customWrapper) {
1386
- const $tagName = name.toLowerCase();
1387
-
1388
- return function(_attributes, _children = null) {
1389
- try {
1390
- const { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
1391
- const element = ElementCreator.createElement($tagName);
1392
- const finalElement = (typeof customWrapper === 'function') ? customWrapper(element) : element;
1413
+ return (_attributes, _children = null) => createHtmlElement(name.toLowerCase(), _attributes, _children, customWrapper);
1414
+ }
1393
1415
 
1394
- ElementCreator.processAttributes(finalElement, attributes);
1395
- ElementCreator.processChildren(children, finalElement);
1416
+ Function.prototype.args = function(...args) {
1417
+ return exports.withValidation(this, args);
1418
+ };
1396
1419
 
1397
- return ElementCreator.setup(finalElement, attributes, customWrapper);
1398
- } catch (error) {
1399
- DebugManager$1.error('ElementCreation', `Error creating ${$tagName}`, error);
1420
+ Function.prototype.cached = function(...args) {
1421
+ let $cache = null;
1422
+ let getCache = function(){ return $cache; };
1423
+ return () => {
1424
+ if(!$cache) {
1425
+ $cache = this.apply(this, args);
1426
+ if($cache.cloneNode) {
1427
+ getCache = function() { return $cache.cloneNode(true); };
1428
+ } else if($cache.$element) {
1429
+ getCache = function() { return new NDElement($cache.$element.cloneNode(true)); };
1430
+ }
1400
1431
  }
1432
+ return getCache();
1401
1433
  };
1402
- }
1403
-
1404
- Function.prototype.args = function(...args) {
1405
- return withValidation(this, args);
1406
1434
  };
1407
1435
 
1408
1436
  Function.prototype.errorBoundary = function(callback) {
@@ -1514,7 +1542,8 @@ var NativeDocument = (function (exports) {
1514
1542
  };
1515
1543
 
1516
1544
  observer.merge = function(values) {
1517
- observer.set([...observer.val(), ...values]);
1545
+ observer.$value.push(...values);
1546
+ observer.trigger({ action: 'merge', args: values });
1518
1547
  };
1519
1548
 
1520
1549
  observer.populateAndRender = function(iteration, callback) {
@@ -2009,20 +2038,15 @@ var NativeDocument = (function (exports) {
2009
2038
  cache.delete(keyId);
2010
2039
  }
2011
2040
 
2012
- try {
2013
- const indexObserver = isIndexRequired ? Observable(indexKey) : null;
2014
- let child = ElementCreator.getChild(callback(item, indexObserver));
2015
- cache.set(keyId, {
2016
- keyId,
2017
- child: child,
2018
- indexObserver: (indexObserver ? new WeakRef(indexObserver) : null)
2019
- });
2020
- keysCache.set(item, keyId);
2021
- return child;
2022
- } catch (e) {
2023
- DebugManager$1.error('ForEach', `Error creating element for key ${keyId}` , e);
2024
- throw e;
2025
- }
2041
+ const indexObserver = isIndexRequired ? Observable(indexKey) : null;
2042
+ let child = ElementCreator.getChild(callback(item, indexObserver));
2043
+ cache.set(keyId, {
2044
+ keyId,
2045
+ child: child,
2046
+ indexObserver: (indexObserver ? new WeakRef(indexObserver) : null)
2047
+ });
2048
+ keysCache.set(item, keyId);
2049
+ return child;
2026
2050
  };
2027
2051
  const getChildByKey = function(keyId) {
2028
2052
  const cacheItem = cache.get(keyId);
@@ -2086,10 +2110,7 @@ var NativeDocument = (function (exports) {
2086
2110
  element.appendElement(fragment, blockEnd);
2087
2111
  },
2088
2112
  removeOne(element, index) {
2089
- let child = getItemChild(element);
2090
- if(child) {
2091
- removeCacheItemByKey(getItemKey(element, index), true);
2092
- }
2113
+ removeCacheItemByKey(getItemKey(element, index), true);
2093
2114
  child = null;
2094
2115
  },
2095
2116
  clear,
@@ -3376,7 +3397,6 @@ var NativeDocument = (function (exports) {
3376
3397
  Router: Router
3377
3398
  });
3378
3399
 
3379
- exports.ArgTypes = ArgTypes;
3380
3400
  exports.ElementCreator = ElementCreator;
3381
3401
  exports.HtmlElementWrapper = HtmlElementWrapper;
3382
3402
  exports.NDElement = NDElement;
@@ -3387,7 +3407,6 @@ var NativeDocument = (function (exports) {
3387
3407
  exports.elements = elements;
3388
3408
  exports.normalizeComponentArgs = normalizeComponentArgs;
3389
3409
  exports.router = router;
3390
- exports.withValidation = withValidation;
3391
3410
 
3392
3411
  return exports;
3393
3412