manyfest 1.0.42 → 1.0.44

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.
Files changed (55) hide show
  1. package/README.md +91 -260
  2. package/dist/manyfest.compatible.js +279 -112
  3. package/dist/manyfest.compatible.js.map +1 -1
  4. package/dist/manyfest.compatible.min.js +1 -1
  5. package/dist/manyfest.compatible.min.js.map +1 -1
  6. package/dist/manyfest.js +280 -112
  7. package/dist/manyfest.js.map +1 -1
  8. package/dist/manyfest.min.js +1 -1
  9. package/dist/manyfest.min.js.map +1 -1
  10. package/docs/.nojekyll +0 -0
  11. package/docs/README.md +108 -0
  12. package/docs/_sidebar.md +17 -0
  13. package/docs/address-notation.md +244 -0
  14. package/docs/cover.md +11 -0
  15. package/docs/hash-translation.md +202 -0
  16. package/docs/index.html +51 -0
  17. package/docs/quickstart.md +203 -0
  18. package/docs/reading.md +339 -0
  19. package/docs/schema-manipulation.md +186 -0
  20. package/docs/schema.md +319 -0
  21. package/docs/validating.md +344 -0
  22. package/docs/writing.md +300 -0
  23. package/package.json +3 -3
  24. package/source/Manyfest-CleanWrapCharacters.js +7 -1
  25. package/source/Manyfest-HashTranslation.js +29 -8
  26. package/source/Manyfest-ObjectAddress-CheckAddressExists.js +31 -17
  27. package/source/Manyfest-ObjectAddress-DeleteValue.js +27 -7
  28. package/source/Manyfest-ObjectAddress-GetValue.js +25 -10
  29. package/source/Manyfest-ObjectAddress-Parser.js +42 -35
  30. package/source/Manyfest-ObjectAddress-SetValue.js +21 -6
  31. package/source/Manyfest-ObjectAddressGeneration.js +23 -12
  32. package/source/Manyfest-ParseConditionals.js +3 -16
  33. package/source/Manyfest-SchemaManipulation.js +44 -21
  34. package/source/Manyfest.js +72 -17
  35. package/test/Manyfest_Performance_tests.js +48 -0
  36. package/types/Manyfest-CleanWrapCharacters.d.ts +7 -1
  37. package/types/Manyfest-CleanWrapCharacters.d.ts.map +1 -1
  38. package/types/Manyfest-HashTranslation.d.ts +34 -7
  39. package/types/Manyfest-HashTranslation.d.ts.map +1 -1
  40. package/types/Manyfest-ObjectAddress-CheckAddressExists.d.ts +23 -4
  41. package/types/Manyfest-ObjectAddress-CheckAddressExists.d.ts.map +1 -1
  42. package/types/Manyfest-ObjectAddress-DeleteValue.d.ts +25 -6
  43. package/types/Manyfest-ObjectAddress-DeleteValue.d.ts.map +1 -1
  44. package/types/Manyfest-ObjectAddress-GetValue.d.ts +26 -6
  45. package/types/Manyfest-ObjectAddress-GetValue.d.ts.map +1 -1
  46. package/types/Manyfest-ObjectAddress-Parser.d.ts +5 -5
  47. package/types/Manyfest-ObjectAddress-Parser.d.ts.map +1 -1
  48. package/types/Manyfest-ObjectAddress-SetValue.d.ts +18 -5
  49. package/types/Manyfest-ObjectAddress-SetValue.d.ts.map +1 -1
  50. package/types/Manyfest-ObjectAddressGeneration.d.ts +25 -4
  51. package/types/Manyfest-ObjectAddressGeneration.d.ts.map +1 -1
  52. package/types/Manyfest-SchemaManipulation.d.ts +47 -6
  53. package/types/Manyfest-SchemaManipulation.d.ts.map +1 -1
  54. package/types/Manyfest.d.ts +35 -12
  55. package/types/Manyfest.d.ts.map +1 -1
package/dist/manyfest.js CHANGED
@@ -175,6 +175,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
175
175
  //
176
176
  // TODO: Should template literals be processed? If so what state do they have access to? That should happen here if so.
177
177
  // TODO: Make a simple class include library with these
178
+ /**
179
+ * @param {string} pCharacter - The character to remove from the start and end of the string
180
+ * @param {string} pString - The string to clean
181
+ *
182
+ * @return {string} The cleaned string
183
+ */
178
184
  const cleanWrapCharacters = (pCharacter, pString) => {
179
185
  if (pString.startsWith(pCharacter) && pString.endsWith(pCharacter)) {
180
186
  return pString.substring(1, pString.length - 1);
@@ -206,15 +212,27 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
206
212
  * @class ManyfestHashTranslation
207
213
  */
208
214
  class ManyfestHashTranslation {
215
+ /**
216
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
217
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
218
+ */
209
219
  constructor(pInfoLog, pErrorLog) {
210
220
  // Wire in logging
211
221
  this.logInfo = typeof pInfoLog === 'function' ? pInfoLog : libSimpleLog;
212
222
  this.logError = typeof pErrorLog === 'function' ? pErrorLog : libSimpleLog;
213
223
  this.translationTable = {};
214
224
  }
225
+
226
+ /**
227
+ * @return {number} The number of translations in the table
228
+ */
215
229
  translationCount() {
216
230
  return Object.keys(this.translationTable).length;
217
231
  }
232
+
233
+ /**
234
+ * @param {object} pTranslation - An object containing source:destination hash pairs to add to the translation table
235
+ */
218
236
  addTranslation(pTranslation) {
219
237
  // This adds a translation in the form of:
220
238
  // { "SourceHash": "DestinationHash", "SecondSourceHash":"SecondDestinationHash" }
@@ -231,15 +249,23 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
231
249
  }
232
250
  });
233
251
  }
252
+
253
+ /**
254
+ * @param {string} pTranslationHash - The source hash to remove from the translation table
255
+ */
234
256
  removeTranslationHash(pTranslationHash) {
235
- if (pTranslationHash in this.translationTable) {
236
- delete this.translationTable[pTranslationHash];
237
- }
257
+ delete this.translationTable[pTranslationHash];
238
258
  }
239
259
 
240
- // This removes translations.
241
- // If passed a string, just removes the single one.
242
- // If passed an object, it does all the source keys.
260
+ /**
261
+ * This removes translations.
262
+ * If passed a string, just removes the single one.
263
+ * If passed an object, it does all the source keys.
264
+ *
265
+ * @param {string|object} pTranslation - Either a source hash string to remove, or an object containing source:destination hash pairs to remove
266
+ *
267
+ * @return {boolean} True if the removal was successful, false otherwise
268
+ */
243
269
  removeTranslation(pTranslation) {
244
270
  if (typeof pTranslation == 'string') {
245
271
  this.removeTranslationHash(pTranslation);
@@ -258,6 +284,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
258
284
  clearTranslations() {
259
285
  this.translationTable = {};
260
286
  }
287
+
288
+ /**
289
+ * @param {string} pTranslation - The source hash to translate
290
+ *
291
+ * @return {string} The translated hash, or the original if no translation exists
292
+ */
261
293
  translate(pTranslation) {
262
294
  if (pTranslation in this.translationTable) {
263
295
  return this.translationTable[pTranslation];
@@ -293,6 +325,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
293
325
  const libSimpleLog = require('./Manyfest-LogToConsole.js');
294
326
  // This is for resolving functions mid-address
295
327
  const libGetObjectValue = require('./Manyfest-ObjectAddress-GetValue.js');
328
+ const fCleanWrapCharacters = require('./Manyfest-CleanWrapCharacters.js');
296
329
 
297
330
  // TODO: Just until this is a fable service.
298
331
  let _MockFable = {
@@ -318,19 +351,32 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
318
351
  * @class ManyfestObjectAddressResolverCheckAddressExists
319
352
  */
320
353
  class ManyfestObjectAddressResolverCheckAddressExists {
354
+ /**
355
+ * @param {function} [pInfoLog] - (optional) Function to use for info logging
356
+ * @param {function} [pErrorLog] - (optional) Function to use for error logging
357
+ */
321
358
  constructor(pInfoLog, pErrorLog) {
322
359
  // Wire in logging
323
360
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
324
361
  this.logError = typeof pErrorLog == 'function' ? pErrorLog : libSimpleLog;
325
362
  this.getObjectValueClass = new libGetObjectValue(this.logInfo, this.logError);
363
+ this.cleanWrapCharacters = fCleanWrapCharacters;
326
364
  }
327
365
 
328
- // Check if an address exists.
329
- //
330
- // This is necessary because the getValueAtAddress function is ambiguous on
331
- // whether the element/property is actually there or not (it returns
332
- // undefined whether the property exists or not). This function checks for
333
- // existance and returns true or false dependent.
366
+ /**
367
+ * Check if an address exists.
368
+ *
369
+ * This is necessary because the getValueAtAddress function is ambiguous on
370
+ * whether the element/property is actually there or not (it returns
371
+ * undefined whether the property exists or not). This function checks for
372
+ * existance and returns true or false dependent.
373
+ *
374
+ * @param {object} pObject - The object to check within
375
+ * @param {string} pAddress - The address to check for
376
+ * @param {object} [pRootObject] - (optional) The root object for function resolution context
377
+ *
378
+ * @return {boolean} - True if the address exists, false if it does not
379
+ */
334
380
  checkAddressExists(pObject, pAddress, pRootObject) {
335
381
  // TODO: Should these throw an error?
336
382
  // Make sure pObject is an object
@@ -463,7 +509,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
463
509
  let tmpFunctionAddress = tmpSubObjectName.substring(0, tmpFunctionStartIndex).trim();
464
510
  //tmpParentAddress = `${tmpParentAddress}${(tmpParentAddress.length > 0) ? '.' : ''}${tmpSubObjectName}`;
465
511
 
466
- if (!typeof pObject[tmpFunctionAddress] == 'function') {
512
+ if (typeof pObject[tmpFunctionAddress] !== 'function') {
467
513
  // The address suggests it is a function, but it is not.
468
514
  return false;
469
515
  }
@@ -478,12 +524,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
478
524
  return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject), tmpNewAddress, tmpRootObject);
479
525
  } catch (pError) {
480
526
  // The function call failed, so the address doesn't exist
481
- libSimpleLog.log("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
527
+ libSimpleLog("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
482
528
  return false;
483
529
  }
484
530
  } else {
485
531
  // The function doesn't exist, so the address doesn't exist
486
- libSimpleLog.log("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
532
+ libSimpleLog("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
487
533
  return false;
488
534
  }
489
535
  } else {
@@ -503,12 +549,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
503
549
  return this.checkAddressExists(pObject[tmpFunctionAddress].apply(pObject, tmpArgumentValues), tmpNewAddress, tmpRootObject);
504
550
  } catch (pError) {
505
551
  // The function call failed, so the address doesn't exist
506
- libSimpleLog.log("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
552
+ libSimpleLog("Error calling function ".concat(tmpFunctionAddress, " (address [").concat(pAddress, "]): ").concat(pError.message));
507
553
  return false;
508
554
  }
509
555
  } else {
510
556
  // The function doesn't exist, so the address doesn't exist
511
- libSimpleLog.log("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
557
+ libSimpleLog("Function ".concat(tmpFunctionAddress, " does not exist (address [").concat(pAddress, "])"));
512
558
  return false;
513
559
  }
514
560
  }
@@ -583,9 +629,9 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
583
629
  }
584
630
  }
585
631
  }
586
- ;
587
632
  module.exports = ManyfestObjectAddressResolverCheckAddressExists;
588
633
  }, {
634
+ "./Manyfest-CleanWrapCharacters.js": 3,
589
635
  "./Manyfest-LogToConsole.js": 5,
590
636
  "./Manyfest-ObjectAddress-GetValue.js": 8,
591
637
  "./Manyfest-ObjectAddress-Parser.js": 9
@@ -619,6 +665,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
619
665
  * @class ManyfestObjectAddressResolverDeleteValue
620
666
  */
621
667
  class ManyfestObjectAddressResolverDeleteValue {
668
+ /**
669
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
670
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
671
+ */
622
672
  constructor(pInfoLog, pErrorLog) {
623
673
  // Wire in logging
624
674
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
@@ -627,11 +677,25 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
627
677
  }
628
678
 
629
679
  // TODO: Dry me
680
+ /**
681
+ * @param {string} pAddress - The address being evaluated
682
+ * @param {object} pRecord - The record being evaluated
683
+ *
684
+ * @return {boolean} True if the record passes the filters, false if it does not
685
+ */
630
686
  checkRecordFilters(pAddress, pRecord) {
631
687
  return fParseConditionals(this, pAddress, pRecord);
632
688
  }
633
689
 
634
- // Delete the value of an element at an address
690
+ /**
691
+ * Delete the value of an element at an address
692
+ *
693
+ * @param {object} pObject - The object to delete the value from
694
+ * @param {string} pAddress - The address to delete the value at
695
+ * @param {string} [pParentAddress] - (optional) The parent address for recursion
696
+ *
697
+ * @return {boolean|object|undefined} - True if the value was deleted, false if it could not be deleted, undefined on error
698
+ */
635
699
  deleteValueAtAddress(pObject, pAddress, pParentAddress) {
636
700
  // Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
637
701
  if (typeof pObject != 'object') return undefined;
@@ -931,17 +995,37 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
931
995
  * @class ManyfestObjectAddressResolverGetValue
932
996
  */
933
997
  class ManyfestObjectAddressResolverGetValue {
998
+ /**
999
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
1000
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
1001
+ */
934
1002
  constructor(pInfoLog, pErrorLog) {
935
1003
  // Wire in logging
936
1004
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
937
1005
  this.logError = typeof pErrorLog == 'function' ? pErrorLog : libSimpleLog;
938
1006
  this.cleanWrapCharacters = fCleanWrapCharacters;
939
1007
  }
1008
+
1009
+ /**
1010
+ * @param {string} pAddress - The address of the record to check
1011
+ * @param {object} pRecord - The record to check against the filters
1012
+ *
1013
+ * @return {boolean} - True if the record passes the filters, false otherwise
1014
+ */
940
1015
  checkRecordFilters(pAddress, pRecord) {
941
1016
  return fParseConditionals(this, pAddress, pRecord);
942
1017
  }
943
1018
 
944
- // Get the value of an element at an address
1019
+ /**
1020
+ * Get the value of an element at an address
1021
+ *
1022
+ * @param {object} pObject - The object to resolve the address against
1023
+ * @param {string} pAddress - The address to resolve
1024
+ * @param {string} [pParentAddress] - (optional) The parent address for back-navigation
1025
+ * @param {object} [pRootObject] - (optional) The root object for function argument resolution
1026
+ *
1027
+ * @return {any} The value at the address, or undefined if not found
1028
+ */
945
1029
  getValueAtAddress(pObject, pAddress, pParentAddress, pRootObject) {
946
1030
  // Make sure pObject (the object we are meant to be recursing) is an object (which could be an array or object)
947
1031
  if (typeof pObject != 'object') {
@@ -1029,7 +1113,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1029
1113
  // 2) The end bracket is after the start bracket
1030
1114
  && _MockFable.DataFormat.stringCountEnclosures(pAddress) > 0) {
1031
1115
  let tmpFunctionAddress = pAddress.substring(0, tmpFunctionStartIndex).trim();
1032
- if (!typeof pObject[tmpFunctionAddress] == 'function') {
1116
+ if (typeof pObject[tmpFunctionAddress] !== 'function') {
1033
1117
  // The address suggests it is a function, but it is not.
1034
1118
  return false;
1035
1119
  }
@@ -1206,7 +1290,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1206
1290
  && _MockFable.DataFormat.stringCountEnclosures(tmpSubObjectName) > 0) {
1207
1291
  let tmpFunctionAddress = tmpSubObjectName.substring(0, tmpFunctionStartIndex).trim();
1208
1292
  tmpParentAddress = "".concat(tmpParentAddress).concat(tmpParentAddress.length > 0 ? '.' : '').concat(tmpSubObjectName);
1209
- if (!typeof pObject[tmpFunctionAddress] == 'function') {
1293
+ if (typeof pObject[tmpFunctionAddress] !== 'function') {
1210
1294
  // The address suggests it is a function, but it is not.
1211
1295
  return false;
1212
1296
  }
@@ -1415,29 +1499,32 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1415
1499
  // Until we shift Manyfest to be a fable service, these three functions were pulled out of
1416
1500
  // fable to aid in parsing functions with nested enclosures.
1417
1501
 
1502
+ const DEFAULT_START_SYMBOL_MAP = {
1503
+ '{': 0,
1504
+ '[': 1,
1505
+ '(': 2
1506
+ };
1507
+ const DEFAULT_END_SYMBOL_MAP = {
1508
+ '}': 0,
1509
+ ']': 1,
1510
+ ')': 2
1511
+ };
1418
1512
  module.exports = {
1419
1513
  /**
1420
1514
  * Count the number of segments in a string, respecting enclosures
1421
- *
1422
- * @param {string} pString
1423
- * @param {string} pSeparator
1424
- * @param {object} pEnclosureStartSymbolMap
1425
- * @param {object} pEnclosureEndSymbolMap
1426
- * @returns the count of segments in the string as a number
1515
+ *
1516
+ * @param {string} pString
1517
+ * @param {string} [pSeparator]
1518
+ * @param {Record<string, number>} [pEnclosureStartSymbolMap]
1519
+ * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1520
+ *
1521
+ * @return {number} - The number of segments in the string
1427
1522
  */
1428
1523
  stringCountSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1429
1524
  let tmpString = typeof pString == 'string' ? pString : '';
1430
1525
  let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1431
- let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1432
- '{': 0,
1433
- '[': 1,
1434
- '(': 2
1435
- };
1436
- let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1437
- '}': 0,
1438
- ']': 1,
1439
- ')': 2
1440
- };
1526
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStartSymbolMap : DEFAULT_START_SYMBOL_MAP;
1527
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEndSymbolMap : DEFAULT_END_SYMBOL_MAP;
1441
1528
  if (pString.length < 1) {
1442
1529
  return 0;
1443
1530
  }
@@ -1468,28 +1555,21 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1468
1555
  },
1469
1556
  /**
1470
1557
  * Get the first segment in a string, respecting enclosures
1471
- *
1472
- * @param {string} pString
1473
- * @param {string} pSeparator
1474
- * @param {object} pEnclosureStartSymbolMap
1475
- * @param {object} pEnclosureEndSymbolMap
1476
- * @returns the first segment in the string as a string
1558
+ *
1559
+ * @param {string} pString
1560
+ * @param {string} [pSeparator]
1561
+ * @param {Record<string, number>} [pEnclosureStartSymbolMap]
1562
+ * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1563
+ *
1564
+ * @return {string} - the first segment in the string as a string
1477
1565
  */
1478
1566
  stringGetFirstSegment: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1479
1567
  let tmpString = typeof pString == 'string' ? pString : '';
1480
1568
  let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1481
- let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1482
- '{': 0,
1483
- '[': 1,
1484
- '(': 2
1485
- };
1486
- let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1487
- '}': 0,
1488
- ']': 1,
1489
- ')': 2
1490
- };
1569
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStartSymbolMap : DEFAULT_START_SYMBOL_MAP;
1570
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEndSymbolMap : DEFAULT_END_SYMBOL_MAP;
1491
1571
  if (pString.length < 1) {
1492
- return 0;
1572
+ return '';
1493
1573
  }
1494
1574
  let tmpEnclosureStack = [];
1495
1575
  for (let i = 0; i < tmpString.length; i++) {
@@ -1517,26 +1597,19 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1517
1597
  },
1518
1598
  /**
1519
1599
  * Get all segments in a string, respecting enclosures
1520
- *
1521
- * @param {string} pString
1522
- * @param {string} pSeparator
1523
- * @param {object} pEnclosureStartSymbolMap
1524
- * @param {object} pEnclosureEndSymbolMap
1525
- * @returns the first segment in the string as a string
1600
+ *
1601
+ * @param {string} pString
1602
+ * @param {string} [pSeparator]
1603
+ * @param {Record<string, number>} [pEnclosureStartSymbolMap]
1604
+ * @param {Record<string, number>} [pEnclosureEndSymbolMap]
1605
+ *
1606
+ * @return {Array<string>} - the segments in the string as an array of strings
1526
1607
  */
1527
1608
  stringGetSegments: (pString, pSeparator, pEnclosureStartSymbolMap, pEnclosureEndSymbolMap) => {
1528
1609
  let tmpString = typeof pString == 'string' ? pString : '';
1529
1610
  let tmpSeparator = typeof pSeparator == 'string' ? pSeparator : '.';
1530
- let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStart : {
1531
- '{': 0,
1532
- '[': 1,
1533
- '(': 2
1534
- };
1535
- let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEnd : {
1536
- '}': 0,
1537
- ']': 1,
1538
- ')': 2
1539
- };
1611
+ let tmpEnclosureStartSymbolMap = typeof pEnclosureStartSymbolMap == 'object' ? pEnclosureStartSymbolMap : DEFAULT_START_SYMBOL_MAP;
1612
+ let tmpEnclosureEndSymbolMap = typeof pEnclosureEndSymbolMap == 'object' ? pEnclosureEndSymbolMap : DEFAULT_END_SYMBOL_MAP;
1540
1613
  let tmpCurrentSegmentStart = 0;
1541
1614
  let tmpSegmentList = [];
1542
1615
  if (pString.length < 1) {
@@ -1576,8 +1649,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1576
1649
  * If no start or end characters are specified, it will default to parentheses. If the string is not a string, it will return 0.
1577
1650
  *
1578
1651
  * @param {string} pString
1579
- * @param {string} pEnclosureStart
1580
- * @param {string} pEnclosureEnd
1652
+ * @param {string} [pEnclosureStart]
1653
+ * @param {string} [pEnclosureEnd]
1581
1654
  * @returns the count of full in the string
1582
1655
  */
1583
1656
  stringCountEnclosures: (pString, pEnclosureStart, pEnclosureEnd) => {
@@ -1606,9 +1679,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1606
1679
  *
1607
1680
  * @param {string} pString
1608
1681
  * @param {number} pEnclosureIndexToGet
1609
- * @param {string} pEnclosureStart
1610
- * @param {string}} pEnclosureEnd
1611
- * @returns {string}
1682
+ * @param {string} [pEnclosureStart]
1683
+ * @param {string} [pEnclosureEnd]
1684
+ *
1685
+ * @return {string} - The value of the enclosure at the specified index
1612
1686
  */
1613
1687
  stringGetEnclosureValueByIndex: (pString, pEnclosureIndexToGet, pEnclosureStart, pEnclosureEnd) => {
1614
1688
  let tmpString = typeof pString == 'string' ? pString : '';
@@ -1684,6 +1758,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1684
1758
  * @class ManyfestObjectAddressSetValue
1685
1759
  */
1686
1760
  class ManyfestObjectAddressSetValue {
1761
+ /**
1762
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
1763
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
1764
+ */
1687
1765
  constructor(pInfoLog, pErrorLog) {
1688
1766
  // Wire in logging
1689
1767
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
@@ -1691,7 +1769,15 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1691
1769
  this.cleanWrapCharacters = fCleanWrapCharacters;
1692
1770
  }
1693
1771
 
1694
- // Set the value of an element at an address
1772
+ /**
1773
+ * Set the value of an element at an address
1774
+ *
1775
+ * @param {object} pObject - The object to set the value in
1776
+ * @param {string} pAddress - The address to set the value at
1777
+ * @param {any} pValue - The value to set at the address
1778
+ *
1779
+ * @return {boolean} True if the value was set, false otherwise
1780
+ */
1695
1781
  setValueAtAddress(pObject, pAddress, pValue) {
1696
1782
  // Make sure pObject is an object
1697
1783
  if (typeof pObject != 'object') return false;
@@ -1910,21 +1996,33 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1910
1996
  * @class ManyfestObjectAddressGeneration
1911
1997
  */
1912
1998
  class ManyfestObjectAddressGeneration {
1999
+ /**
2000
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
2001
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
2002
+ */
1913
2003
  constructor(pInfoLog, pErrorLog) {
1914
2004
  // Wire in logging
1915
2005
  this.logInfo = typeof pInfoLog == 'function' ? pInfoLog : libSimpleLog;
1916
2006
  this.logError = typeof pErrorLog == 'function' ? pErrorLog : libSimpleLog;
1917
2007
  }
1918
2008
 
1919
- // generateAddressses
1920
- //
1921
- // This flattens an object into a set of key:value pairs for *EVERY SINGLE
1922
- // POSSIBLE ADDRESS* in the object. It can get ... really insane really
1923
- // quickly. This is not meant to be used directly to generate schemas, but
1924
- // instead as a starting point for scripts or UIs.
1925
- //
1926
- // This will return a mega set of key:value pairs with all possible schema
1927
- // permutations and default values (when not an object) and everything else.
2009
+ /**
2010
+ * generateAddressses
2011
+ *
2012
+ * This flattens an object into a set of key:value pairs for *EVERY SINGLE
2013
+ * POSSIBLE ADDRESS* in the object. It can get ... really insane really
2014
+ * quickly. This is not meant to be used directly to generate schemas, but
2015
+ * instead as a starting point for scripts or UIs.
2016
+ *
2017
+ * This will return a mega set of key:value pairs with all possible schema
2018
+ * permutations and default values (when not an object) and everything else.
2019
+ *
2020
+ * @param {any} pObject - The object to generate addresses for
2021
+ * @param {string} [pBaseAddress] - (optional) The base address to start from
2022
+ * @param {object} [pSchema] - (optional) The schema object to append to
2023
+ *
2024
+ * @return {object} The generated schema object
2025
+ */
1928
2026
  generateAddressses(pObject, pBaseAddress, pSchema) {
1929
2027
  let tmpBaseAddress = typeof pBaseAddress == 'string' ? pBaseAddress : '';
1930
2028
  let tmpSchema = typeof pSchema == 'object' ? pSchema : {};
@@ -1937,7 +2035,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1937
2035
  InSchema: false
1938
2036
  };
1939
2037
  if (tmpObjectType == 'object' && pObject == null) {
1940
- tmpObjectType = 'null';
2038
+ tmpObjectType = 'undefined';
1941
2039
  }
1942
2040
  switch (tmpObjectType) {
1943
2041
  case 'string':
@@ -1952,7 +2050,6 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1952
2050
  tmpSchema[tmpBaseAddress] = tmpSchemaObjectEntry;
1953
2051
  break;
1954
2052
  case 'undefined':
1955
- case 'null':
1956
2053
  tmpSchemaObjectEntry.DataType = 'Any';
1957
2054
  tmpSchemaObjectEntry.Default = pObject;
1958
2055
  tmpSchema[tmpBaseAddress] = tmpSchemaObjectEntry;
@@ -2137,30 +2234,41 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2137
2234
  * @class ManyfestSchemaManipulation
2138
2235
  */
2139
2236
  class ManyfestSchemaManipulation {
2237
+ /**
2238
+ * @param {function} [pInfoLog] - (optional) A logging function for info messages
2239
+ * @param {function} [pErrorLog] - (optional) A logging function for error messages
2240
+ */
2140
2241
  constructor(pInfoLog, pErrorLog) {
2141
2242
  // Wire in logging
2142
2243
  this.logInfo = typeof pInfoLog === 'function' ? pInfoLog : libSimpleLog;
2143
2244
  this.logError = typeof pErrorLog === 'function' ? pErrorLog : libSimpleLog;
2144
2245
  }
2145
2246
 
2146
- // This translates the default address mappings to something different.
2147
- //
2148
- // For instance you can pass in manyfest schema descriptor object:
2149
- // {
2150
- // "Address.Of.a": { "Hash": "a", "Type": "Number" },
2151
- // "Address.Of.b": { "Hash": "b", "Type": "Number" }
2152
- // }
2153
- //
2154
- //
2155
- // And then an address mapping (basically a Hash->Address map)
2156
- // {
2157
- // "a": "New.Address.Of.a",
2158
- // "b": "New.Address.Of.b"
2159
- // }
2160
- //
2161
- // NOTE: This mutates the schema object permanently, altering the base hash.
2162
- // If there is a collision with an existing address, it can lead to overwrites.
2163
- // TODO: Discuss what should happen on collisions.
2247
+ /**
2248
+ * This translates the default address mappings to something different.
2249
+ *
2250
+ * For instance you can pass in manyfest schema descriptor object:
2251
+ * {
2252
+ * "Address.Of.a": { "Hash": "a", "Type": "Number" },
2253
+ * "Address.Of.b": { "Hash": "b", "Type": "Number" }
2254
+ * }
2255
+ *
2256
+ *
2257
+ * And then an address mapping (basically a Hash->Address map)
2258
+ * {
2259
+ * "a": "New.Address.Of.a",
2260
+ * "b": "New.Address.Of.b"
2261
+ * }
2262
+ *
2263
+ * NOTE: This mutates the schema object permanently, altering the base hash.
2264
+ * If there is a collision with an existing address, it can lead to overwrites.
2265
+ * TODO: Discuss what should happen on collisions.
2266
+ *
2267
+ * @param {object} pManyfestSchemaDescriptors - The manyfest schema descriptors to resolve address mappings for
2268
+ * @param {object} pAddressMapping - The address mapping object to use for remapping
2269
+ *
2270
+ * @return {boolean} True if successful, false if there was an error
2271
+ */
2164
2272
  resolveAddressMappings(pManyfestSchemaDescriptors, pAddressMapping) {
2165
2273
  if (typeof pManyfestSchemaDescriptors != 'object') {
2166
2274
  this.logError("Attempted to resolve address mapping but the descriptor was not an object.");
@@ -2182,8 +2290,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2182
2290
  let tmpAddressMappingSet = Object.keys(pAddressMapping);
2183
2291
  tmpAddressMappingSet.forEach(pInputAddress => {
2184
2292
  let tmpNewDescriptorAddress = pAddressMapping[pInputAddress];
2185
- let tmpOldDescriptorAddress = false;
2186
- let tmpDescriptor = false;
2293
+ let tmpOldDescriptorAddress = null;
2294
+ let tmpDescriptor;
2187
2295
 
2188
2296
  // See if there is a matching descriptor either by Address directly or Hash
2189
2297
  if (pInputAddress in pManyfestSchemaDescriptors) {
@@ -2208,12 +2316,26 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2208
2316
  });
2209
2317
  return true;
2210
2318
  }
2319
+
2320
+ /**
2321
+ * @param {object} pManyfestSchemaDescriptors - The manyfest schema descriptors to resolve address mappings for
2322
+ * @param {object} pAddressMapping - The address mapping object to use for remapping
2323
+ *
2324
+ * @return {object} A new object containing the remapped schema descriptors
2325
+ */
2211
2326
  safeResolveAddressMappings(pManyfestSchemaDescriptors, pAddressMapping) {
2212
2327
  // This returns the descriptors as a new object, safely remapping without mutating the original schema Descriptors
2213
2328
  let tmpManyfestSchemaDescriptors = JSON.parse(JSON.stringify(pManyfestSchemaDescriptors));
2214
2329
  this.resolveAddressMappings(tmpManyfestSchemaDescriptors, pAddressMapping);
2215
2330
  return tmpManyfestSchemaDescriptors;
2216
2331
  }
2332
+
2333
+ /**
2334
+ * @param {object} pManyfestSchemaDescriptorsDestination - The destination manyfest schema descriptors
2335
+ * @param {object} pManyfestSchemaDescriptorsSource - The source manyfest schema descriptors
2336
+ *
2337
+ * @return {object} A new object containing the merged schema descriptors
2338
+ */
2217
2339
  mergeAddressMappings(pManyfestSchemaDescriptorsDestination, pManyfestSchemaDescriptorsSource) {
2218
2340
  if (typeof pManyfestSchemaDescriptorsSource != 'object' || typeof pManyfestSchemaDescriptorsDestination != 'object') {
2219
2341
  this.logError("Attempted to merge two schema descriptors but both were not objects.");
@@ -2279,8 +2401,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2279
2401
  super(pFable, pManifest, pServiceHash);
2280
2402
  }
2281
2403
 
2404
+ /** @type {import('fable')} */
2405
+ this.fable;
2282
2406
  /** @type {Record<string, any>} */
2283
2407
  this.options;
2408
+ /** @type {string} */
2409
+ this.Hash;
2410
+ /** @type {string} */
2411
+ this.UUID;
2284
2412
  this.serviceType = 'Manifest';
2285
2413
 
2286
2414
  // Wire in logging
@@ -2310,9 +2438,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2310
2438
  if (!('strict' in this.options)) {
2311
2439
  this.options.strict = false;
2312
2440
  }
2441
+
2442
+ /** @type {string} */
2313
2443
  this.scope = undefined;
2444
+ /** @type {Array<string>} */
2314
2445
  this.elementAddresses = undefined;
2446
+ /** @type {Record<string, string>} */
2315
2447
  this.elementHashes = undefined;
2448
+ /** @type {Record<string, ManifestDescriptor>} */
2316
2449
  this.elementDescriptors = undefined;
2317
2450
  this.reset();
2318
2451
  if (typeof this.options === 'object') {
@@ -2338,7 +2471,27 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2338
2471
  clone() {
2339
2472
  // Make a copy of the options in-place
2340
2473
  let tmpNewOptions = JSON.parse(JSON.stringify(this.options));
2341
- let tmpNewManyfest = new Manyfest(this.getManifest(), this.logInfo, this.logError, tmpNewOptions);
2474
+ let tmpNewManyfest = new Manyfest(this.fable, tmpNewOptions, this.Hash);
2475
+ tmpNewManyfest.logInfo = this.logInfo;
2476
+ tmpNewManyfest.logError = this.logError;
2477
+ //FIXME: mostly written by co-pilot
2478
+ const {
2479
+ Scope,
2480
+ Descriptors,
2481
+ HashTranslations
2482
+ } = this.getManifest();
2483
+ tmpNewManyfest.scope = Scope;
2484
+ tmpNewManyfest.elementDescriptors = Descriptors;
2485
+ tmpNewManyfest.elementAddresses = Object.keys(Descriptors);
2486
+ // Rebuild the element hashes
2487
+ for (let i = 0; i < tmpNewManyfest.elementAddresses.length; i++) {
2488
+ let tmpAddress = tmpNewManyfest.elementAddresses[i];
2489
+ let tmpDescriptor = tmpNewManyfest.elementDescriptors[tmpAddress];
2490
+ tmpNewManyfest.elementHashes[tmpAddress] = tmpAddress;
2491
+ if ('Hash' in tmpDescriptor) {
2492
+ tmpNewManyfest.elementHashes[tmpDescriptor.Hash] = tmpAddress;
2493
+ }
2494
+ }
2342
2495
 
2343
2496
  // Import the hash translations
2344
2497
  tmpNewManyfest.hashTranslations.addTranslation(this.hashTranslations.translationTable);
@@ -2346,9 +2499,15 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2346
2499
  }
2347
2500
 
2348
2501
  // Deserialize a Manifest from a string
2502
+ /**
2503
+ * @param {string} pManifestString - The manifest string to deserialize
2504
+ *
2505
+ * @return {Manyfest} The deserialized manifest
2506
+ */
2349
2507
  deserialize(pManifestString) {
2350
2508
  // TODO: Add guards for bad manifest string
2351
- return this.loadManifest(JSON.parse(pManifestString));
2509
+ this.loadManifest(JSON.parse(pManifestString));
2510
+ return this;
2352
2511
  }
2353
2512
 
2354
2513
  // Load a manifest from an object
@@ -2387,16 +2546,25 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
2387
2546
  if ('HashTranslations' in tmpManifest) {
2388
2547
  if (typeof tmpManifest.HashTranslations === 'object') {
2389
2548
  for (let i = 0; i < tmpManifest.HashTranslations.length; i++) {
2390
- // Each translation is
2549
+ // Each translation is
2550
+ //FIXME: ?????????
2391
2551
  }
2392
2552
  }
2393
2553
  }
2394
2554
  }
2395
2555
 
2396
- // Serialize the Manifest to a string
2556
+ /**
2557
+ * Serialize the Manifest to a string
2558
+ *
2559
+ * @return {string} - The serialized manifest
2560
+ */
2397
2561
  serialize() {
2398
2562
  return JSON.stringify(this.getManifest());
2399
2563
  }
2564
+
2565
+ /**
2566
+ * @return {{ Scope: string, Descriptors: Record<string, ManifestDescriptor>, HashTranslations: Record<string, string> }} - A copy of the manifest state.
2567
+ */
2400
2568
  getManifest() {
2401
2569
  return {
2402
2570
  Scope: this.scope,