@sparted/shared-library 0.0.12 → 0.0.14

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 (132) hide show
  1. package/_virtual/_tslib.js +11 -38
  2. package/_virtual/_tslib.js.map +1 -1
  3. package/array/array-to-map.js +6 -9
  4. package/array/array-to-map.js.map +1 -1
  5. package/array/get-values-from-keys.js +2 -2
  6. package/array/get-values-from-keys.js.map +1 -1
  7. package/date/constants.d.ts +4 -0
  8. package/date/constants.js +7 -0
  9. package/date/constants.js.map +1 -0
  10. package/date/convert.d.ts +2 -0
  11. package/date/convert.js +7 -0
  12. package/date/convert.js.map +1 -0
  13. package/date/format-minutes.d.ts +1 -0
  14. package/date/format-minutes.js +12 -0
  15. package/date/format-minutes.js.map +1 -0
  16. package/date/get-time-diff-as-string.d.ts +47 -0
  17. package/date/get-time-diff-as-string.js +124 -0
  18. package/date/get-time-diff-as-string.js.map +1 -0
  19. package/date/index.d.ts +4 -0
  20. package/date/index.js +4 -0
  21. package/date/index.js.map +1 -0
  22. package/formatting/format-number.d.ts +1 -0
  23. package/formatting/format-number.js +14 -0
  24. package/formatting/format-number.js.map +1 -0
  25. package/formatting/index.d.ts +1 -0
  26. package/formatting/index.js +2 -0
  27. package/formatting/index.js.map +1 -0
  28. package/fp/run-while.js +6 -7
  29. package/fp/run-while.js.map +1 -1
  30. package/http/encode-search-object.d.ts +7 -0
  31. package/http/encode-search-object.js +27 -0
  32. package/http/encode-search-object.js.map +1 -0
  33. package/http/fetch-with-timeout.d.ts +8 -0
  34. package/http/fetch-with-timeout.js +18 -0
  35. package/http/fetch-with-timeout.js.map +1 -0
  36. package/http/index.d.ts +2 -0
  37. package/http/index.js +3 -0
  38. package/http/index.js.map +1 -0
  39. package/index.d.ts +6 -0
  40. package/index.js +13 -0
  41. package/index.js.map +1 -1
  42. package/linked-list/apply-diff-linked-list.d.ts +2 -0
  43. package/linked-list/apply-diff-linked-list.js +27 -0
  44. package/linked-list/apply-diff-linked-list.js.map +1 -0
  45. package/linked-list/create-linked-list.d.ts +2 -0
  46. package/linked-list/create-linked-list.js +66 -0
  47. package/linked-list/create-linked-list.js.map +1 -0
  48. package/linked-list/find-linked-list.d.ts +2 -0
  49. package/linked-list/find-linked-list.js +24 -0
  50. package/linked-list/find-linked-list.js.map +1 -0
  51. package/linked-list/get-linked-list.d.ts +2 -0
  52. package/linked-list/get-linked-list.js +9 -0
  53. package/linked-list/get-linked-list.js.map +1 -0
  54. package/linked-list/index.d.ts +2 -0
  55. package/linked-list/index.js +2 -0
  56. package/linked-list/index.js.map +1 -0
  57. package/linked-list/insert-linked-list.d.ts +2 -0
  58. package/linked-list/insert-linked-list.js +28 -0
  59. package/linked-list/insert-linked-list.js.map +1 -0
  60. package/linked-list/linked-list-utils.d.ts +23 -0
  61. package/linked-list/linked-list-utils.js +96 -0
  62. package/linked-list/linked-list-utils.js.map +1 -0
  63. package/linked-list/reduce-linked-list.d.ts +2 -0
  64. package/linked-list/reduce-linked-list.js +17 -0
  65. package/linked-list/reduce-linked-list.js.map +1 -0
  66. package/linked-list/remove-linked-list.d.ts +2 -0
  67. package/linked-list/remove-linked-list.js +24 -0
  68. package/linked-list/remove-linked-list.js.map +1 -0
  69. package/linked-list/type.d.ts +34 -0
  70. package/linked-list/update-linked-list.d.ts +2 -0
  71. package/linked-list/update-linked-list.js +20 -0
  72. package/linked-list/update-linked-list.js.map +1 -0
  73. package/linked-list/walk-list-item-record.d.ts +15 -0
  74. package/linked-list/while-linked-list.d.ts +2 -0
  75. package/linked-list/while-linked-list.js +28 -0
  76. package/linked-list/while-linked-list.js.map +1 -0
  77. package/math/clamp-number.d.ts +2 -0
  78. package/math/clamp-number.js +9 -0
  79. package/math/clamp-number.js.map +1 -0
  80. package/math/index.d.ts +4 -0
  81. package/math/index.js +5 -0
  82. package/math/index.js.map +1 -0
  83. package/math/interpolate.d.ts +2 -0
  84. package/math/interpolate.js +16 -0
  85. package/math/interpolate.js.map +1 -0
  86. package/math/number-range.d.ts +6 -0
  87. package/math/number-range.js +12 -0
  88. package/math/number-range.js.map +1 -0
  89. package/math/random-number.d.ts +2 -0
  90. package/math/random-number.js +9 -0
  91. package/math/random-number.js.map +1 -0
  92. package/object/index.d.ts +1 -0
  93. package/object/index.js +2 -0
  94. package/object/index.js.map +1 -0
  95. package/object/merge-deep.d.ts +2 -0
  96. package/object/merge-deep.js +21 -0
  97. package/object/merge-deep.js.map +1 -0
  98. package/package.json +2 -1
  99. package/parsing/parse-boolean.js +1 -1
  100. package/parsing/parse-boolean.js.map +1 -1
  101. package/parsing/parse-enum.js +3 -3
  102. package/parsing/parse-enum.js.map +1 -1
  103. package/parsing/parse-number.js +2 -2
  104. package/parsing/parse-number.js.map +1 -1
  105. package/predicates/is-function.js +1 -1
  106. package/predicates/is-function.js.map +1 -1
  107. package/predicates/is-null.js +1 -1
  108. package/predicates/is-null.js.map +1 -1
  109. package/predicates/is-object.js +1 -1
  110. package/predicates/is-object.js.map +1 -1
  111. package/predicates/is-primitive.js +4 -4
  112. package/predicates/is-primitive.js.map +1 -1
  113. package/predicates/is-undefined.js +1 -1
  114. package/predicates/is-undefined.js.map +1 -1
  115. package/predicates/is-uuid.d.ts +1 -0
  116. package/promise/delay.d.ts +1 -0
  117. package/promise/delay.js +6 -0
  118. package/promise/delay.js.map +1 -0
  119. package/promise/execute-or-resolve-default.js +2 -2
  120. package/promise/execute-or-resolve-default.js.map +1 -1
  121. package/promise/execute-with-delay.d.ts +1 -1
  122. package/promise/execute-with-delay.js +6 -13
  123. package/promise/execute-with-delay.js.map +1 -1
  124. package/promise/index.d.ts +1 -0
  125. package/promise/index.js +1 -0
  126. package/promise/index.js.map +1 -1
  127. package/string/replace-in-template.js +8 -10
  128. package/string/replace-in-template.js.map +1 -1
  129. package/types/general.d.ts +1 -0
  130. package/types/index.d.ts +1 -0
  131. package/types/object.d.ts +13 -0
  132. package/types/search.d.ts +24 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-diff-linked-list.js","sources":["../../src/linked-list/apply-diff-linked-list.ts"],"sourcesContent":["import { LinkedList, LinkedListItem, ManipulationConfig } from './type';\n\nexport const applyDiffLinkedList = <T extends LinkedListItem>(\n before: T | null,\n after: T | null,\n list: LinkedList<T>,\n) => {\n // Delete\n if (!after && before) {\n return list.remove(before.id);\n }\n\n // Insert\n if (!before && after) {\n return list.insert(after);\n }\n\n // For the following commands, none of the 2 items can be null\n // We dont use && because checks are already done above, but ts cannot infer that they cannot be null afterwards\n if (!before || !after) {\n throw new Error('Cannot have both before & after as null');\n }\n\n if (before.id !== after.id) {\n throw new Error('Cannot change id of a ListNode');\n }\n\n const listWithPotentialReorder = before.nextId === after.nextId\n ? list\n : list\n .remove(before.id)\n .insert(after);\n\n return listWithPotentialReorder.update(after);\n};"],"names":[],"mappings":"AAEa,MAAA,mBAAmB,GAAG,CACjC,MAAgB,EAChB,KAAe,EACf,IAAmB,KACjB;;AAEF,IAAA,IAAI,CAAC,KAAK,IAAI,MAAM,EAAE;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC/B,KAAA;;AAGD,IAAA,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE;AACpB,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3B,KAAA;;;AAID,IAAA,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE;AACrB,QAAA,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;AAC5D,KAAA;AAED,IAAA,IAAI,MAAM,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,EAAE;AAC1B,QAAA,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;AACnD,KAAA;IAED,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;AAC7D,UAAE,IAAI;AACN,UAAE,IAAI;AACH,aAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;aACjB,MAAM,CAAC,KAAK,CAAC,CAAC;AAEnB,IAAA,OAAO,wBAAwB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChD;;;;"}
@@ -0,0 +1,2 @@
1
+ import { LinkedListItem, LinkedList } from './type';
2
+ export declare const createLinkedList: <T extends LinkedListItem>(headId: string | null, items: Record<string, T>) => LinkedList<T>;
@@ -0,0 +1,66 @@
1
+ import { reduceLinkedList } from './reduce-linked-list.js';
2
+ import { findLinkedList } from './find-linked-list.js';
3
+ import { whileLinkedList } from './while-linked-list.js';
4
+ import { walkListItemRecord } from './linked-list-utils.js';
5
+ import { removeLinkedList } from './remove-linked-list.js';
6
+ import { insertLinkedList } from './insert-linked-list.js';
7
+ import { getLinkedList } from './get-linked-list.js';
8
+ import { updateLinkedList } from './update-linked-list.js';
9
+ import { applyDiffLinkedList } from './apply-diff-linked-list.js';
10
+
11
+ const createLinkedList = (headId, items) => {
12
+ const head = headId ? items[headId] : null;
13
+ if (head === undefined) {
14
+ throw new Error('Cannot find the head.');
15
+ }
16
+ const list = { headId, items };
17
+ const { isDoubleLinked, count } = walkListItemRecord((acc, current) => {
18
+ const newCount = acc.count + 1;
19
+ const isDoubleLinked = current.previousId !== undefined;
20
+ const incompatibleFormats = acc.isDoubleLinked !== undefined && acc.isDoubleLinked !== isDoubleLinked;
21
+ if (incompatibleFormats || (isDoubleLinked && current.previousId !== acc.previousId)) {
22
+ throw new Error('Invalid previous node in the linked list');
23
+ }
24
+ return {
25
+ result: {
26
+ previousId: current.id,
27
+ count: newCount,
28
+ isDoubleLinked,
29
+ }
30
+ };
31
+ }, {
32
+ initValue: {
33
+ isDoubleLinked: undefined,
34
+ count: 0,
35
+ previousId: null,
36
+ },
37
+ startId: headId,
38
+ items,
39
+ });
40
+ const manipulationConfig = {
41
+ factory: (list) => createLinkedList(list.headId, list.items),
42
+ /**
43
+ * At this point isDoubleLinked cannot be undefined
44
+ */
45
+ isDoubleLinkList: isDoubleLinked,
46
+ list,
47
+ };
48
+ const linkedList = {
49
+ head,
50
+ items,
51
+ size: count,
52
+ isDoubleLinked: isDoubleLinked,
53
+ reduce: (cb, initValue) => reduceLinkedList(cb, initValue, list),
54
+ find: (predicate) => findLinkedList(predicate, list),
55
+ while: (predicate, startId) => whileLinkedList(predicate, list, startId),
56
+ remove: (id) => removeLinkedList(id, manipulationConfig),
57
+ insert: (item) => insertLinkedList(item, manipulationConfig),
58
+ get: (id) => getLinkedList(id, list),
59
+ update: (item) => updateLinkedList(item, manipulationConfig),
60
+ applyDiff: (before, after) => applyDiffLinkedList(before, after, linkedList),
61
+ };
62
+ return linkedList;
63
+ };
64
+
65
+ export { createLinkedList };
66
+ //# sourceMappingURL=create-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-linked-list.js","sources":["../../src/linked-list/create-linked-list.ts"],"sourcesContent":["import { LinkedListItem, LinkedList, ManipulationConfig } from './type';\n\nimport { reduceLinkedList } from './reduce-linked-list';\nimport { findLinkedList } from './find-linked-list';\nimport { whileLinkedList } from './while-linked-list';\nimport { walkListItemRecord } from './linked-list-utils';\nimport { removeLinkedList } from './remove-linked-list';\nimport { insertLinkedList } from './insert-linked-list';\nimport { getLinkedList } from './get-linked-list';\nimport { updateLinkedList } from './update-linked-list';\nimport { applyDiffLinkedList } from './apply-diff-linked-list';\n\ntype LinkedListValidation = {\n isDoubleLinked?: boolean,\n previousId: null | string,\n count: number,\n}\n\nexport const createLinkedList = <T extends LinkedListItem>(headId: string | null, items: Record<string, T>): LinkedList<T> => {\n const head = headId ? items[headId] : null;\n\n if (head === undefined) {\n throw new Error('Cannot find the head.');\n }\n\n const list = { headId, items };\n\n const { isDoubleLinked, count } = walkListItemRecord((acc, current) => {\n const newCount = acc.count + 1;\n const isDoubleLinked = current.previousId !== undefined;\n const incompatibleFormats = acc.isDoubleLinked !== undefined && acc.isDoubleLinked !== isDoubleLinked;\n\n if (incompatibleFormats || (isDoubleLinked && current.previousId !== acc.previousId)) {\n throw new Error('Invalid previous node in the linked list');\n }\n\n return {\n result: {\n previousId: current.id,\n count: newCount,\n isDoubleLinked,\n }\n }\n }, {\n initValue: {\n isDoubleLinked: undefined,\n count: 0,\n previousId: null,\n } as LinkedListValidation,\n startId: headId,\n items,\n });\n\n const manipulationConfig: ManipulationConfig<T> = {\n factory: (list) => createLinkedList(list.headId, list.items),\n /**\n * At this point isDoubleLinked cannot be undefined\n */\n isDoubleLinkList: isDoubleLinked!,\n list,\n };\n\n const linkedList: LinkedList<T> = {\n head,\n items,\n size: count,\n isDoubleLinked: isDoubleLinked!,\n reduce: (cb, initValue) => reduceLinkedList(cb, initValue, list),\n find: (predicate) => findLinkedList(predicate, list),\n while: (predicate, startId) => whileLinkedList(predicate, list, startId),\n remove: (id) => removeLinkedList(id, manipulationConfig),\n insert: (item) => insertLinkedList(item, manipulationConfig),\n get: (id) => getLinkedList(id, list),\n update: (item) => updateLinkedList(item, manipulationConfig),\n applyDiff: (before, after) => applyDiffLinkedList(before, after, linkedList),\n };\n\n return linkedList;\n};"],"names":[],"mappings":";;;;;;;;;;MAkBa,gBAAgB,GAAG,CAA2B,MAAqB,EAAE,KAAwB,KAAmB;AAC3H,IAAA,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAE3C,IAAI,IAAI,KAAK,SAAS,EAAE;AACtB,QAAA,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;AAC1C,KAAA;AAED,IAAA,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAE/B,IAAA,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,CAAC,GAAG,EAAE,OAAO,KAAI;AACpE,QAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;AAC/B,QAAA,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC;AACxD,QAAA,MAAM,mBAAmB,GAAG,GAAG,CAAC,cAAc,KAAK,SAAS,IAAI,GAAG,CAAC,cAAc,KAAK,cAAc,CAAC;AAEtG,QAAA,IAAI,mBAAmB,KAAK,cAAc,IAAI,OAAO,CAAC,UAAU,KAAK,GAAG,CAAC,UAAU,CAAC,EAAE;AACpF,YAAA,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;AAC7D,SAAA;QAED,OAAO;AACL,YAAA,MAAM,EAAE;gBACN,UAAU,EAAE,OAAO,CAAC,EAAE;AACtB,gBAAA,KAAK,EAAE,QAAQ;gBACf,cAAc;AACf,aAAA;SACF,CAAA;AACH,KAAC,EAAE;AACD,QAAA,SAAS,EAAE;AACT,YAAA,cAAc,EAAE,SAAS;AACzB,YAAA,KAAK,EAAE,CAAC;AACR,YAAA,UAAU,EAAE,IAAI;AACO,SAAA;AACzB,QAAA,OAAO,EAAE,MAAM;QACf,KAAK;AACN,KAAA,CAAC,CAAC;AAEH,IAAA,MAAM,kBAAkB,GAA0B;AAChD,QAAA,OAAO,EAAE,CAAC,IAAI,KAAK,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;AAC5D;;AAEG;AACH,QAAA,gBAAgB,EAAE,cAAe;QACjC,IAAI;KACL,CAAC;AAEF,IAAA,MAAM,UAAU,GAAkB;QAChC,IAAI;QACJ,KAAK;AACL,QAAA,IAAI,EAAE,KAAK;AACX,QAAA,cAAc,EAAE,cAAe;AAC/B,QAAA,MAAM,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC;QAChE,IAAI,EAAE,CAAC,SAAS,KAAK,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC;AACpD,QAAA,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC;QACxE,MAAM,EAAE,CAAC,EAAE,KAAK,gBAAgB,CAAC,EAAE,EAAE,kBAAkB,CAAC;QACxD,MAAM,EAAE,CAAC,IAAI,KAAK,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,CAAC;QAC5D,GAAG,EAAE,CAAC,EAAE,KAAK,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC;QACpC,MAAM,EAAE,CAAC,IAAI,KAAK,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,CAAC;AAC5D,QAAA,SAAS,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC;KAC7E,CAAC;AAEF,IAAA,OAAO,UAAU,CAAC;AACpB;;;;"}
@@ -0,0 +1,2 @@
1
+ import { LinkedListItem, ItemPredicate, HeadAndItems } from './type';
2
+ export declare const findLinkedList: <Item extends LinkedListItem>(predicate: ItemPredicate<Item>, list: HeadAndItems<Item>) => Item | null;
@@ -0,0 +1,24 @@
1
+ import { walkListItemRecord } from './linked-list-utils.js';
2
+
3
+ const findLinkedList = (predicate, list) => {
4
+ return walkListItemRecord((acc, item) => {
5
+ if (predicate(item)) {
6
+ return {
7
+ result: item,
8
+ control: {
9
+ stop: true,
10
+ },
11
+ };
12
+ }
13
+ return {
14
+ result: acc,
15
+ };
16
+ }, {
17
+ initValue: null,
18
+ items: list.items,
19
+ startId: list.headId,
20
+ });
21
+ };
22
+
23
+ export { findLinkedList };
24
+ //# sourceMappingURL=find-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-linked-list.js","sources":["../../src/linked-list/find-linked-list.ts"],"sourcesContent":["import { LinkedListItem, ItemPredicate, HeadAndItems } from './type';\nimport { walkListItemRecord } from './linked-list-utils';\n\nexport const findLinkedList = <Item extends LinkedListItem>(\n predicate: ItemPredicate<Item>,\n list: HeadAndItems<Item>,\n): Item | null => {\n const { headId } = list;\n\n return walkListItemRecord(\n (acc, item) => {\n if (predicate(item)) {\n return {\n result: item,\n control: {\n stop: true,\n },\n };\n };\n\n return {\n result: acc,\n };\n }, {\n initValue: null as Item | null,\n items: list.items,\n startId: list.headId,\n },\n );\n};\n"],"names":[],"mappings":";;MAGa,cAAc,GAAG,CAC5B,SAA8B,EAC9B,IAAwB,KACT;AAGf,IAAA,OAAO,kBAAkB,CACvB,CAAC,GAAG,EAAE,IAAI,KAAI;AACZ,QAAA,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE;YACnB,OAAO;AACL,gBAAA,MAAM,EAAE,IAAI;AACZ,gBAAA,OAAO,EAAE;AACP,oBAAA,IAAI,EAAE,IAAI;AACX,iBAAA;aACF,CAAC;AACH,SAAA;QAED,OAAO;AACL,YAAA,MAAM,EAAE,GAAG;SACZ,CAAC;AACJ,KAAC,EAAE;AACD,QAAA,SAAS,EAAE,IAAmB;QAC9B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,MAAM;AACrB,KAAA,CACF,CAAC;AACJ;;;;"}
@@ -0,0 +1,2 @@
1
+ import { HeadAndItems, LinkedListItem } from './type';
2
+ export declare const getLinkedList: <T extends LinkedListItem>(id: string, list: HeadAndItems<T>) => T | null;
@@ -0,0 +1,9 @@
1
+ const getLinkedList = (id, list) => {
2
+ if (list.items[id]) {
3
+ return list.items[id];
4
+ }
5
+ return null;
6
+ };
7
+
8
+ export { getLinkedList };
9
+ //# sourceMappingURL=get-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-linked-list.js","sources":["../../src/linked-list/get-linked-list.ts"],"sourcesContent":["import { HeadAndItems, LinkedListItem } from './type';\n\nexport const getLinkedList = <T extends LinkedListItem>(id: string, list: HeadAndItems<T>) => {\n if (list.items[id]) {\n return list.items[id];\n }\n\n return null;\n}"],"names":[],"mappings":"MAEa,aAAa,GAAG,CAA2B,EAAU,EAAE,IAAqB,KAAI;AAC3F,IAAA,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AAClB,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACvB,KAAA;AAED,IAAA,OAAO,IAAI,CAAC;AACd;;;;"}
@@ -0,0 +1,2 @@
1
+ export * from './create-linked-list';
2
+ export * from './type';
@@ -0,0 +1,2 @@
1
+ export { createLinkedList } from './create-linked-list.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import { ManipulationConfig, LinkedListItem } from './type';
2
+ export declare const insertLinkedList: <T extends LinkedListItem>(item: T, config: ManipulationConfig<T>) => import("./type").LinkedList<T>;
@@ -0,0 +1,28 @@
1
+ import { assertItemCompatibility, assertPresence, findPreviousId, assertNewNodePosition } from './linked-list-utils.js';
2
+
3
+ const insertLinkedList = (item, config) => {
4
+ const { isDoubleLinkList, list, factory } = config;
5
+ assertItemCompatibility(item, isDoubleLinkList);
6
+ assertPresence(item.nextId, list.items);
7
+ assertPresence(item.previousId, list.items);
8
+ const previousId = isDoubleLinkList
9
+ ? item.previousId
10
+ : findPreviousId(item.nextId, list);
11
+ assertNewNodePosition(item, {
12
+ previousId,
13
+ list,
14
+ });
15
+ const newHeadId = item.nextId === list.headId ? item.id : list.headId;
16
+ const newItems = Object.assign(Object.assign(Object.assign(Object.assign({}, list.items), (previousId ? {
17
+ [previousId]: Object.assign(Object.assign({}, list.items[previousId]), { nextId: item.id }),
18
+ } : {})), (isDoubleLinkList && item.nextId ? {
19
+ [item.nextId]: Object.assign(Object.assign({}, list.items[item.nextId]), (isDoubleLinkList ? { previousId: item.id } : {})),
20
+ } : {})), { [item.id]: item });
21
+ return factory({
22
+ headId: newHeadId,
23
+ items: newItems,
24
+ });
25
+ };
26
+
27
+ export { insertLinkedList };
28
+ //# sourceMappingURL=insert-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insert-linked-list.js","sources":["../../src/linked-list/insert-linked-list.ts"],"sourcesContent":["import { ManipulationConfig, LinkedListItem } from './type';\n\nimport {\n findPreviousId,\n assertItemCompatibility,\n assertPresence,\n assertNewNodePosition,\n} from './linked-list-utils';\n\nexport const insertLinkedList = <T extends LinkedListItem>(item: T, config: ManipulationConfig<T>) => {\n const { isDoubleLinkList, list, factory } = config;\n\n assertItemCompatibility(item, isDoubleLinkList);\n assertPresence(item.nextId, list.items);\n assertPresence(item.previousId, list.items);\n\n const previousId = isDoubleLinkList\n ? item.previousId!\n : findPreviousId(item.nextId, list);\n\n assertNewNodePosition(item, {\n previousId,\n list,\n });\n\n const newHeadId = item.nextId === list.headId ? item.id : list.headId;\n const newItems = {\n ...list.items,\n ...(previousId ? {\n [previousId]: {\n ...list.items[previousId],\n nextId: item.id,\n },\n } : {}),\n ...(isDoubleLinkList && item.nextId ? {\n [item.nextId]: {\n ...list.items[item.nextId],\n ...(isDoubleLinkList ? { previousId: item.id } : {}),\n },\n } : {}),\n [item.id]: item,\n };\n\n return factory({\n headId: newHeadId,\n items: newItems,\n });\n};\n"],"names":[],"mappings":";;MASa,gBAAgB,GAAG,CAA2B,IAAO,EAAE,MAA6B,KAAI;IACnG,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;AAEnD,IAAA,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAChD,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAE5C,MAAM,UAAU,GAAG,gBAAgB;UAC/B,IAAI,CAAC,UAAW;UAChB,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAEtC,qBAAqB,CAAC,IAAI,EAAE;QAC1B,UAAU;QACV,IAAI;AACL,KAAA,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;IACtE,MAAM,QAAQ,GACT,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,IAAI,CAAC,KAAK,IACT,UAAU,GAAG;AACf,QAAA,CAAC,UAAU,GACN,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KACzB,MAAM,EAAE,IAAI,CAAC,EAAE,EAChB,CAAA;AACF,KAAA,GAAG,EAAE,EACH,GAAC,gBAAgB,IAAI,IAAI,CAAC,MAAM,GAAG;AACpC,QAAA,CAAC,IAAI,CAAC,MAAM,GACP,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CACvB,GAAC,gBAAgB,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,EACpD;AACF,KAAA,GAAG,EAAE,EACN,EAAA,EAAA,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,GAChB,CAAC;AAEF,IAAA,OAAO,OAAO,CAAC;AACb,QAAA,MAAM,EAAE,SAAS;AACjB,QAAA,KAAK,EAAE,QAAQ;AAChB,KAAA,CAAC,CAAC;AACL;;;;"}
@@ -0,0 +1,23 @@
1
+ import { LinkedListItem, HeadAndItems } from './type';
2
+ export declare type WalkConfig<T extends LinkedListItem, Result> = {
3
+ startId: string | null;
4
+ items: Record<string, T>;
5
+ initValue: Result;
6
+ };
7
+ declare type WalkCallbackResult<R> = {
8
+ result: R;
9
+ control?: {
10
+ stop?: boolean;
11
+ };
12
+ };
13
+ export declare type WalkCallback<Item, Result> = (accumulator: Result, current: Item) => WalkCallbackResult<Result>;
14
+ export declare const walkListItemRecord: <T extends LinkedListItem, Result>(callback: WalkCallback<T, Result>, config: WalkConfig<T, Result>) => Result;
15
+ export declare const findPreviousId: <T extends LinkedListItem>(id: string | null, list: HeadAndItems<T>) => string | null;
16
+ export declare const assertItemCompatibility: <T extends LinkedListItem>(item: T, isDoubleLinkList: boolean) => void;
17
+ export declare const assertPresence: (id: string | null | undefined, items: Record<string, unknown>) => void;
18
+ declare type PositionAssertionConfig = {
19
+ previousId: string | null;
20
+ list: HeadAndItems<LinkedListItem>;
21
+ };
22
+ export declare const assertNewNodePosition: <T extends LinkedListItem>(item: T, config: PositionAssertionConfig) => void;
23
+ export {};
@@ -0,0 +1,96 @@
1
+ import { runWhile } from '../fp/run-while.js';
2
+
3
+ const walkListItemRecord = (callback, config) => {
4
+ var _a;
5
+ const { items, startId, initValue } = config;
6
+ const visited = new Set();
7
+ const totalNodes = Object.keys(items).length;
8
+ const { iterationCount, result } = runWhile({
9
+ iterationLimit: totalNodes + 1,
10
+ initialValue: {
11
+ currentId: startId,
12
+ accumulator: initValue,
13
+ control: {
14
+ stop: false,
15
+ },
16
+ },
17
+ predicate: ({ control, currentId }) => {
18
+ const stop = control === null || control === void 0 ? void 0 : control.stop;
19
+ const forcedStop = stop === undefined ? false : stop;
20
+ /**
21
+ * Stop early or when the end is reached
22
+ */
23
+ return !forcedStop && currentId !== null;
24
+ },
25
+ callback: (current) => {
26
+ if (visited.has(current.currentId)) {
27
+ throw new Error('Infinite loop found');
28
+ }
29
+ visited.add(current.currentId);
30
+ const currentItem = items[current.currentId];
31
+ if (!currentItem) {
32
+ throw new Error('Cul de sac detected');
33
+ }
34
+ const { result, control } = callback(current.accumulator, currentItem);
35
+ return {
36
+ accumulator: result,
37
+ currentId: currentItem.nextId,
38
+ control: control,
39
+ };
40
+ },
41
+ });
42
+ /**
43
+ * When force stopping the walk, we will always have unvisited
44
+ * nodes, so we skip this check.
45
+ */
46
+ if (iterationCount !== totalNodes && ((_a = result.control) === null || _a === void 0 ? void 0 : _a.stop) !== true) {
47
+ throw new Error('Isolated nodes found');
48
+ }
49
+ return result.accumulator;
50
+ };
51
+ const findPreviousId = (id, list) => {
52
+ if (id === list.headId) {
53
+ return null;
54
+ }
55
+ return walkListItemRecord((acc, current) => {
56
+ if (current.nextId === id) {
57
+ return {
58
+ result: current.id,
59
+ control: {
60
+ stop: true,
61
+ },
62
+ };
63
+ }
64
+ return {
65
+ result: acc,
66
+ };
67
+ }, {
68
+ initValue: null,
69
+ startId: list.headId,
70
+ items: list.items,
71
+ });
72
+ };
73
+ const assertItemCompatibility = (item, isDoubleLinkList) => {
74
+ const incompatibleWithDoubleLinks = item.previousId === undefined && isDoubleLinkList;
75
+ const incompatibleWithSingleLink = item.previousId !== undefined && !isDoubleLinkList;
76
+ if (incompatibleWithDoubleLinks || incompatibleWithSingleLink) {
77
+ throw new Error(`Node is incompatible with the list (id: ${item.id})`);
78
+ }
79
+ };
80
+ const assertPresence = (id, items) => {
81
+ if (id && !items[id]) {
82
+ throw new Error(`Node not found in the list (id: ${id})`);
83
+ }
84
+ };
85
+ const assertNewNodePosition = (item, config) => {
86
+ const { previousId, list } = config;
87
+ const insertionMiddleError = previousId && list.items[previousId].nextId !== item.nextId;
88
+ const insertionTailError = previousId && item.nextId === null && list.items[previousId].nextId !== null;
89
+ const insertionHeadError = previousId === null && item.nextId !== list.headId;
90
+ if (insertionMiddleError || insertionTailError || insertionHeadError) {
91
+ throw new Error(`Invalid position for given node (id: ${item.id})`);
92
+ }
93
+ };
94
+
95
+ export { assertItemCompatibility, assertNewNodePosition, assertPresence, findPreviousId, walkListItemRecord };
96
+ //# sourceMappingURL=linked-list-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linked-list-utils.js","sources":["../../src/linked-list/linked-list-utils.ts"],"sourcesContent":["import { runWhile } from '../fp';\nimport { LinkedListItem, HeadAndItems} from './type';\n\nexport type WalkConfig<T extends LinkedListItem, Result> = {\n startId: string | null,\n items: Record<string, T>,\n initValue: Result,\n}\n\ntype WalkCallbackResult<R> = {\n result: R,\n control?: {\n stop?: boolean,\n },\n};\n\nexport type WalkCallback<Item, Result> = (accumulator: Result, current: Item) => WalkCallbackResult<Result>;\n\ntype RunWhileValue<T> = {\n currentId: string | null,\n accumulator: T,\n control: WalkCallbackResult<any>['control'],\n}\n\nexport const walkListItemRecord = <T extends LinkedListItem, Result>(\n callback: WalkCallback<T, Result>,\n config: WalkConfig<T, Result>,\n) => {\n const { items, startId, initValue } = config;\n const visited = new Set();\n const totalNodes = Object.keys(items).length;\n\n const { iterationCount, result } = runWhile({\n iterationLimit: totalNodes + 1,\n initialValue: {\n currentId: startId, \n accumulator: initValue,\n control: {\n stop: false,\n },\n } as RunWhileValue<Result>,\n predicate: ({ control, currentId }) => {\n const stop = control?.stop;\n const forcedStop = stop === undefined ? false : stop;\n\n /**\n * Stop early or when the end is reached\n */\n return !forcedStop && currentId !== null;\n },\n callback: (current) => {\n if (visited.has(current.currentId)) {\n throw new Error('Infinite loop found');\n }\n\n visited.add(current.currentId);\n\n const currentItem = items[current.currentId!];\n\n if (!currentItem) {\n throw new Error('Cul de sac detected');\n }\n\n const { result, control } = callback(current.accumulator, currentItem);\n\n return {\n accumulator: result,\n currentId: currentItem.nextId,\n control: control,\n };\n },\n });\n\n /**\n * When force stopping the walk, we will always have unvisited\n * nodes, so we skip this check.\n */\n if (iterationCount !== totalNodes && result.control?.stop !== true) {\n throw new Error('Isolated nodes found');\n }\n\n return result.accumulator;\n};\n\nexport const findPreviousId = <T extends LinkedListItem>(id: string | null, list: HeadAndItems<T>) => {\n if (id === list.headId) {\n return null;\n }\n\n return walkListItemRecord(\n (acc, current) => {\n if (current.nextId === id) {\n return {\n result: current.id,\n control: {\n stop: true,\n },\n };\n }\n\n return {\n result: acc,\n }\n },\n {\n initValue: null as null | string,\n startId: list.headId,\n items: list.items,\n }\n )\n};\n\nexport const assertItemCompatibility = <T extends LinkedListItem>(item: T, isDoubleLinkList: boolean) => {\n const incompatibleWithDoubleLinks = item.previousId === undefined && isDoubleLinkList;\n const incompatibleWithSingleLink = item.previousId !== undefined && !isDoubleLinkList;\n\n if (incompatibleWithDoubleLinks || incompatibleWithSingleLink) {\n throw new Error(`Node is incompatible with the list (id: ${item.id})`);\n }\n}\n\nexport const assertPresence = (id: string | null | undefined, items: Record<string, unknown>) => {\n if (id && !items[id]) {\n throw new Error(`Node not found in the list (id: ${id})`);\n }\n}\n\ntype PositionAssertionConfig = {\n previousId: string | null,\n list: HeadAndItems<LinkedListItem>,\n};\n\nexport const assertNewNodePosition = <T extends LinkedListItem>(item: T, config: PositionAssertionConfig) => {\n const { previousId, list } = config;\n\n const insertionMiddleError = previousId && list.items[previousId].nextId !== item.nextId;\n const insertionTailError = previousId && item.nextId === null && list.items[previousId].nextId !== null;\n const insertionHeadError = previousId === null && item.nextId !== list.headId;\n\n if (insertionMiddleError || insertionTailError || insertionHeadError) {\n throw new Error(`Invalid position for given node (id: ${item.id})`);\n }\n}"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { ReduceCallback, LinkedListItem, HeadAndItems } from './type';
2
+ export declare const reduceLinkedList: <Item extends LinkedListItem, Result>(cb: ReduceCallback<Item, Result>, initValue: Result, list: HeadAndItems<Item>) => Result;
@@ -0,0 +1,17 @@
1
+ import { walkListItemRecord } from './linked-list-utils.js';
2
+
3
+ const reduceLinkedList = (cb, initValue, list) => {
4
+ const { items, headId } = list;
5
+ return walkListItemRecord((acc, current) => {
6
+ return {
7
+ result: cb(acc, current),
8
+ };
9
+ }, {
10
+ startId: headId,
11
+ items,
12
+ initValue,
13
+ });
14
+ };
15
+
16
+ export { reduceLinkedList };
17
+ //# sourceMappingURL=reduce-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reduce-linked-list.js","sources":["../../src/linked-list/reduce-linked-list.ts"],"sourcesContent":["import { ReduceCallback, LinkedListItem, HeadAndItems } from './type';\nimport { walkListItemRecord } from './linked-list-utils';\n\nexport const reduceLinkedList = <Item extends LinkedListItem, Result>(\n cb: ReduceCallback<Item, Result>,\n initValue: Result,\n list: HeadAndItems<Item>,\n): Result => {\n const { items, headId } = list;\n\n return walkListItemRecord((acc, current) => {\n return {\n result: cb(acc, current),\n };\n }, {\n startId: headId,\n items,\n initValue,\n });\n};\n"],"names":[],"mappings":";;AAGa,MAAA,gBAAgB,GAAG,CAC9B,EAAgC,EAChC,SAAiB,EACjB,IAAwB,KACd;AACV,IAAA,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;AAE/B,IAAA,OAAO,kBAAkB,CAAC,CAAC,GAAG,EAAE,OAAO,KAAI;QACzC,OAAO;AACL,YAAA,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC;SACzB,CAAC;AACJ,KAAC,EAAE;AACD,QAAA,OAAO,EAAE,MAAM;QACf,KAAK;QACL,SAAS;AACV,KAAA,CAAC,CAAC;AACL;;;;"}
@@ -0,0 +1,2 @@
1
+ import { ManipulationConfig, LinkedListItem } from './type';
2
+ export declare const removeLinkedList: <T extends LinkedListItem>(id: string, config: ManipulationConfig<T>) => import("./type").LinkedList<T>;
@@ -0,0 +1,24 @@
1
+ import { __rest } from '../_virtual/_tslib.js';
2
+ import { assertPresence, findPreviousId } from './linked-list-utils.js';
3
+
4
+ const removeLinkedList = (id, config) => {
5
+ const { isDoubleLinkList, list, factory } = config;
6
+ const _a = list.items, _b = id, itemToDelete = _a[_b], otherItems = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
7
+ assertPresence(id, list.items);
8
+ const previousId = isDoubleLinkList
9
+ ? itemToDelete.previousId
10
+ : findPreviousId(id, list);
11
+ const newHeadId = previousId === null ? itemToDelete.nextId : list.headId;
12
+ const newItems = Object.assign(Object.assign(Object.assign({}, otherItems), (previousId ? {
13
+ [previousId]: Object.assign(Object.assign({}, otherItems[previousId]), { nextId: itemToDelete.nextId }),
14
+ } : {})), (isDoubleLinkList && itemToDelete.nextId ? {
15
+ [itemToDelete.nextId]: Object.assign(Object.assign({}, otherItems[itemToDelete.nextId]), (isDoubleLinkList ? { previousId } : {}))
16
+ } : {}));
17
+ return factory({
18
+ headId: newHeadId,
19
+ items: newItems,
20
+ });
21
+ };
22
+
23
+ export { removeLinkedList };
24
+ //# sourceMappingURL=remove-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-linked-list.js","sources":["../../src/linked-list/remove-linked-list.ts"],"sourcesContent":["import { ManipulationConfig, LinkedListItem } from './type';\nimport { assertPresence, findPreviousId } from './linked-list-utils';\n\nexport const removeLinkedList = <T extends LinkedListItem>(id: string, config: ManipulationConfig<T>) => {\n const { isDoubleLinkList, list, factory } = config;\n const { [id]: itemToDelete, ...otherItems } = list.items;\n\n assertPresence(id, list.items);\n\n const previousId = isDoubleLinkList\n ? itemToDelete.previousId!\n : findPreviousId(id, list);\n\n const newHeadId = previousId === null ? itemToDelete.nextId : list.headId;\n const newItems = {\n ...otherItems,\n ...(previousId ? {\n [previousId]: {\n ...otherItems[previousId],\n nextId: itemToDelete.nextId,\n },\n } : {}),\n ...(isDoubleLinkList && itemToDelete.nextId ? {\n [itemToDelete.nextId]: {\n ...otherItems[itemToDelete.nextId],\n ...(isDoubleLinkList ? { previousId } : {}),\n }\n } : {}),\n };\n\n return factory({\n headId: newHeadId,\n items: newItems,\n });\n};"],"names":[],"mappings":";;;MAGa,gBAAgB,GAAG,CAA2B,EAAU,EAAE,MAA6B,KAAI;IACtG,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;AACnD,IAAA,MAA8C,EAAA,GAAA,IAAI,CAAC,KAAK,EAAhD,EAAC,GAAA,EAAG,EAAE,YAAY,SAAA,EAAK,UAAU,GAAnC,MAAA,CAAA,EAAA,EAAA,CAAA,OAAA,EAAA,KAAA,QAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,CAAqC,CAAa,CAAC;AAEzD,IAAA,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAE/B,MAAM,UAAU,GAAG,gBAAgB;UAC/B,YAAY,CAAC,UAAW;AAC1B,UAAE,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;AAE7B,IAAA,MAAM,SAAS,GAAG,UAAU,KAAK,IAAI,GAAG,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC1E,MAAM,QAAQ,iDACT,UAAU,CAAA,GACT,UAAU,GAAG;AACf,QAAA,CAAC,UAAU,GACN,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,UAAU,CAAC,UAAU,CAAC,CAAA,EAAA,EACzB,MAAM,EAAE,YAAY,CAAC,MAAM,EAC5B,CAAA;AACF,KAAA,GAAG,EAAE,EACH,GAAC,gBAAgB,IAAI,YAAY,CAAC,MAAM,GAAG;QAC5C,CAAC,YAAY,CAAC,MAAM,GAAC,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAChB,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA,GAC9B,gBAAgB,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,EAC3C;AACF,KAAA,GAAG,EAAE,EACP,CAAC;AAEF,IAAA,OAAO,OAAO,CAAC;AACb,QAAA,MAAM,EAAE,SAAS;AACjB,QAAA,KAAK,EAAE,QAAQ;AAChB,KAAA,CAAC,CAAC;AACL;;;;"}
@@ -0,0 +1,34 @@
1
+ export declare type LinkedListItem = {
2
+ id: string;
3
+ nextId: string | null;
4
+ previousId?: string | null;
5
+ };
6
+ export declare type HeadAndItems<T extends LinkedListItem> = {
7
+ headId: string | null;
8
+ items: {
9
+ [id: string]: T;
10
+ };
11
+ };
12
+ export declare type ReduceCallback<Item, Result> = (accumulator: Result, current: Item) => Result;
13
+ export declare type ItemPredicate<Item> = (item: Item) => boolean;
14
+ export declare type ManipulationConfig<T extends LinkedListItem> = {
15
+ isDoubleLinkList: boolean;
16
+ list: HeadAndItems<T>;
17
+ factory: (list: HeadAndItems<T>) => LinkedList<T>;
18
+ };
19
+ export declare type LinkedList<T extends LinkedListItem> = {
20
+ readonly head: T | null;
21
+ readonly items: {
22
+ [id: string]: T;
23
+ };
24
+ readonly size: number;
25
+ readonly isDoubleLinked: boolean;
26
+ readonly reduce: <Result>(cb: ReduceCallback<T, Result>, init: Result) => Result;
27
+ readonly find: (predicate: ItemPredicate<T>) => T | null;
28
+ readonly while: (predicate: ItemPredicate<T>, startId?: string) => string[];
29
+ readonly remove: (id: string) => LinkedList<T>;
30
+ readonly insert: (item: T) => LinkedList<T>;
31
+ readonly get: (id: string) => T | null;
32
+ readonly update: (item: T) => LinkedList<T>;
33
+ readonly applyDiff: (before: T | null, after: T | null) => LinkedList<T>;
34
+ };
@@ -0,0 +1,2 @@
1
+ import { ManipulationConfig, LinkedListItem } from './type';
2
+ export declare const updateLinkedList: <T extends LinkedListItem>(item: T, config: ManipulationConfig<T>) => import("./type").LinkedList<T>;
@@ -0,0 +1,20 @@
1
+ import { __rest } from '../_virtual/_tslib.js';
2
+ import { assertPresence } from './linked-list-utils.js';
3
+
4
+ const updateLinkedList = (item, config) => {
5
+ const { list, factory } = config;
6
+ assertPresence(item.id, list.items);
7
+ /**
8
+ * This method should not update any ids.
9
+ */
10
+ const updatableProperties = __rest(item, ["nextId", "previousId", "id"]);
11
+ const currentItem = list.items[item.id];
12
+ const newItems = Object.assign(Object.assign({}, list.items), { [item.id]: Object.assign(Object.assign({}, currentItem), updatableProperties) });
13
+ return factory({
14
+ headId: list.headId,
15
+ items: newItems,
16
+ });
17
+ };
18
+
19
+ export { updateLinkedList };
20
+ //# sourceMappingURL=update-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-linked-list.js","sources":["../../src/linked-list/update-linked-list.ts"],"sourcesContent":["import { ManipulationConfig, LinkedListItem } from './type';\nimport { assertPresence } from './linked-list-utils';\n\nexport const updateLinkedList = <T extends LinkedListItem>(item: T, config: ManipulationConfig<T>) => {\n const { list, factory } = config;\n\n assertPresence(item.id, list.items);\n\n /**\n * This method should not update any ids.\n */\n const { nextId, previousId, id, ...updatableProperties } = item;\n const currentItem = list.items[item.id];\n\n const newItems = {\n ...list.items,\n [item.id]: {\n ...currentItem,\n ...updatableProperties,\n },\n };\n\n return factory({\n headId: list.headId,\n items: newItems,\n });\n};\n"],"names":[],"mappings":";;;MAGa,gBAAgB,GAAG,CAA2B,IAAO,EAAG,MAA6B,KAAI;AACpG,IAAA,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAEjC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AAEpC;;AAEG;AACH,IAAA,MAAmC,mBAAmB,GAAK,MAAA,CAAA,IAAI,EAAzD,CAAA,QAAA,EAAA,YAAA,EAAA,IAAA,CAAkD,EAAQ;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAExC,IAAA,MAAM,QAAQ,GACT,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,IAAI,CAAC,KAAK,KACb,CAAC,IAAI,CAAC,EAAE,GACH,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,WAAW,CACX,EAAA,mBAAmB,IAEzB,CAAC;AAEF,IAAA,OAAO,OAAO,CAAC;QACb,MAAM,EAAE,IAAI,CAAC,MAAM;AACnB,QAAA,KAAK,EAAE,QAAQ;AAChB,KAAA,CAAC,CAAC;AACL;;;;"}
@@ -0,0 +1,15 @@
1
+ import { LinkedListItem } from './type';
2
+ export declare type WalkConfig<T extends LinkedListItem, Result> = {
3
+ startId: string | null;
4
+ items: Record<string, T>;
5
+ initValue: Result;
6
+ };
7
+ declare type WalkCallbackResult<R> = {
8
+ result: R;
9
+ control?: {
10
+ stop?: boolean;
11
+ };
12
+ };
13
+ export declare type WalkCallback<Item, Result> = (accumulator: Result, current: Item) => WalkCallbackResult<Result>;
14
+ export declare const walkListItemRecord: <T extends LinkedListItem, Result>(callback: WalkCallback<T, Result>, config: WalkConfig<T, Result>) => Result;
15
+ export {};
@@ -0,0 +1,2 @@
1
+ import { LinkedListItem, ItemPredicate, HeadAndItems } from './type';
2
+ export declare const whileLinkedList: <Item extends LinkedListItem>(predicate: ItemPredicate<Item>, list: HeadAndItems<Item>, startId?: string) => string[];
@@ -0,0 +1,28 @@
1
+ import { walkListItemRecord } from './linked-list-utils.js';
2
+
3
+ const whileLinkedList = (predicate, list, startId) => {
4
+ if (startId && !list.items[startId]) {
5
+ throw new Error('Cannot start from a node that does not exist');
6
+ }
7
+ return walkListItemRecord((acc, item) => {
8
+ const itemMatched = predicate(item);
9
+ if (itemMatched) {
10
+ return {
11
+ result: [...acc, item.id],
12
+ };
13
+ }
14
+ return {
15
+ result: acc,
16
+ control: {
17
+ stop: true,
18
+ },
19
+ };
20
+ }, {
21
+ initValue: [],
22
+ startId: startId || list.headId,
23
+ items: list.items,
24
+ });
25
+ };
26
+
27
+ export { whileLinkedList };
28
+ //# sourceMappingURL=while-linked-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"while-linked-list.js","sources":["../../src/linked-list/while-linked-list.ts"],"sourcesContent":["\n\nimport { LinkedListItem, ItemPredicate, HeadAndItems } from './type';\nimport { walkListItemRecord } from './linked-list-utils';\n\nexport const whileLinkedList = <Item extends LinkedListItem>(\n predicate: ItemPredicate<Item>,\n list: HeadAndItems<Item>,\n startId?: string,\n): string[] => {\n if (startId && !list.items[startId]) {\n throw new Error('Cannot start from a node that does not exist');\n }\n\n return walkListItemRecord(\n (acc, item) => {\n const itemMatched = predicate(item);\n\n if (itemMatched) {\n return {\n result: [...acc, item.id],\n };\n }\n\n return {\n result: acc,\n control: {\n stop: true,\n },\n };\n }, {\n initValue: [] as string[],\n startId: startId || list.headId,\n items: list.items,\n },\n );\n};\n"],"names":[],"mappings":";;AAKa,MAAA,eAAe,GAAG,CAC7B,SAA8B,EAC9B,IAAwB,EACxB,OAAgB,KACJ;IACZ,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;AACnC,QAAA,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;AACjE,KAAA;AAED,IAAA,OAAO,kBAAkB,CACvB,CAAC,GAAG,EAAE,IAAI,KAAI;AACZ,QAAA,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAEpC,QAAA,IAAI,WAAW,EAAE;YACf,OAAO;gBACL,MAAM,EAAE,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;aAC1B,CAAC;AACH,SAAA;QAED,OAAO;AACL,YAAA,MAAM,EAAE,GAAG;AACX,YAAA,OAAO,EAAE;AACP,gBAAA,IAAI,EAAE,IAAI;AACX,aAAA;SACF,CAAC;AACJ,KAAC,EAAE;AACD,QAAA,SAAS,EAAE,EAAc;AACzB,QAAA,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;AAClB,KAAA,CACF,CAAC;AACJ;;;;"}
@@ -0,0 +1,2 @@
1
+ import type { NumberRange } from './number-range';
2
+ export declare const clampNumber: (num: number, { min, max }: NumberRange) => number;
@@ -0,0 +1,9 @@
1
+ import { assertNumberRange } from './number-range.js';
2
+
3
+ const clampNumber = (num, { min, max }) => {
4
+ assertNumberRange({ min, max });
5
+ return Math.min(Math.max(num, min), max);
6
+ };
7
+
8
+ export { clampNumber };
9
+ //# sourceMappingURL=clamp-number.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clamp-number.js","sources":["../../src/math/clamp-number.ts"],"sourcesContent":["import { assertNumberRange } from './number-range';\nimport type { NumberRange } from './number-range';\n\nexport const clampNumber = (num: number, { min, max }: NumberRange) => {\n assertNumberRange({ min, max });\n\n return Math.min(Math.max(num, min), max);\n};"],"names":[],"mappings":";;AAGO,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAe,KAAI;AACpE,IAAA,iBAAiB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;AAEhC,IAAA,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3C;;;;"}
@@ -0,0 +1,4 @@
1
+ export * from './clamp-number';
2
+ export * from './interpolate';
3
+ export * from './number-range';
4
+ export * from './random-number';
package/math/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { clampNumber } from './clamp-number.js';
2
+ export { interpolate } from './interpolate.js';
3
+ export { assertNumberRange, isNumberInRange } from './number-range.js';
4
+ export { randomNumber } from './random-number.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
@@ -0,0 +1,2 @@
1
+ export declare type RangeArray = [number, number];
2
+ export declare const interpolate: (num: number, inputRange: RangeArray, outputRange: RangeArray) => number;
@@ -0,0 +1,16 @@
1
+ import { isNumberInRange } from './number-range.js';
2
+
3
+ const interpolate = (num, inputRange, outputRange) => {
4
+ const [x1, x2] = inputRange;
5
+ const [y1, y2] = outputRange;
6
+ if (x1 > x2) {
7
+ throw new Error('interpolate: inputRange[0] should not be superior to inputRange[1]');
8
+ }
9
+ if (!isNumberInRange(num, { min: x1, max: x2 })) {
10
+ throw new Error(`interpolate: input number {${num}} is not in range of {${x1}}-{${x2}}`);
11
+ }
12
+ return y1 + ((num - x1) / (x2 - x1)) * (y2 - y1);
13
+ };
14
+
15
+ export { interpolate };
16
+ //# sourceMappingURL=interpolate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolate.js","sources":["../../src/math/interpolate.ts"],"sourcesContent":["import { isNumberInRange } from './number-range';\n\nexport type RangeArray = [number, number];\n\nexport const interpolate = (num: number, inputRange: RangeArray, outputRange: RangeArray) => {\n const [x1, x2] = inputRange;\n const [y1, y2] = outputRange;\n\n if (x1 > x2) {\n throw new Error('interpolate: inputRange[0] should not be superior to inputRange[1]');\n }\n\n if (!isNumberInRange(num, { min: x1, max: x2 })) {\n throw new Error(`interpolate: input number {${num}} is not in range of {${x1}}-{${x2}}`);\n }\n\n return y1 + ((num - x1) / (x2 - x1)) * (y2 - y1);\n};"],"names":[],"mappings":";;AAIa,MAAA,WAAW,GAAG,CAAC,GAAW,EAAE,UAAsB,EAAE,WAAuB,KAAI;AAC1F,IAAA,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU,CAAC;AAC5B,IAAA,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC;IAE7B,IAAI,EAAE,GAAG,EAAE,EAAE;AACX,QAAA,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;AACvF,KAAA;AAED,IAAA,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE;QAC/C,MAAM,IAAI,KAAK,CAAC,CAA8B,2BAAA,EAAA,GAAG,CAAyB,sBAAA,EAAA,EAAE,CAAM,GAAA,EAAA,EAAE,CAAG,CAAA,CAAA,CAAC,CAAC;AAC1F,KAAA;IAED,OAAO,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AACnD;;;;"}
@@ -0,0 +1,6 @@
1
+ export declare type NumberRange = {
2
+ min: number;
3
+ max: number;
4
+ };
5
+ export declare const assertNumberRange: (range: NumberRange) => void;
6
+ export declare const isNumberInRange: (num: number, { min, max }: NumberRange) => boolean;
@@ -0,0 +1,12 @@
1
+ const assertNumberRange = (range) => {
2
+ if (range.min > range.max) {
3
+ throw new Error('Invalid number range: min must be lower than or equal to max');
4
+ }
5
+ };
6
+ const isNumberInRange = (num, { min, max }) => {
7
+ assertNumberRange({ min, max });
8
+ return num >= min && num <= max;
9
+ };
10
+
11
+ export { assertNumberRange, isNumberInRange };
12
+ //# sourceMappingURL=number-range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-range.js","sources":["../../src/math/number-range.ts"],"sourcesContent":["export type NumberRange = {\n min: number,\n max: number,\n};\n\nexport const assertNumberRange = (range: NumberRange) => {\n if (range.min > range.max) {\n throw new Error('Invalid number range: min must be lower than or equal to max');\n }\n};\n\nexport const isNumberInRange = (num: number, { min, max }: NumberRange) => {\n assertNumberRange({ min, max });\n\n return num >= min && num <= max;\n};\n"],"names":[],"mappings":"AAKa,MAAA,iBAAiB,GAAG,CAAC,KAAkB,KAAI;AACtD,IAAA,IAAI,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE;AACzB,QAAA,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;AACjF,KAAA;AACH,EAAE;AAEK,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAe,KAAI;AACxE,IAAA,iBAAiB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;AAEhC,IAAA,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC;AAClC;;;;"}
@@ -0,0 +1,2 @@
1
+ import type { NumberRange } from './number-range';
2
+ export declare const randomNumber: ({ min, max }: NumberRange) => number;