« get me outta code hell

data: withNearbyItemFromList: 'filter', 'valuePastEdge' inputs - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-04-23 14:38:43 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-04-23 14:38:43 -0300
commitca8121c2225fe7dfa97c604ca08ae241e5fe84d7 (patch)
treea174c151ccf5828e16425f06941b4c0ac3d696d5 /src
parent4dc11e5ee9599802e920d6661145f495407df986 (diff)
data: withNearbyItemFromList: 'filter', 'valuePastEdge' inputs
The documentation for this one indicated valuePastEdge existed.
It didn't! This adds it at the same time as mainly adding a new
'filter' input, and implementing the guts from the ground up
rather than reusing #sugar's `atOffset`.
Diffstat (limited to 'src')
-rw-r--r--src/data/composite/data/withNearbyItemFromList.js52
1 files changed, 42 insertions, 10 deletions
diff --git a/src/data/composite/data/withNearbyItemFromList.js b/src/data/composite/data/withNearbyItemFromList.js
index 83a8cc21..5e165219 100644
--- a/src/data/composite/data/withNearbyItemFromList.js
+++ b/src/data/composite/data/withNearbyItemFromList.js
@@ -9,6 +9,10 @@
 //  - If the 'valuePastEdge' input is provided, that value will be output
 //    instead of null.
 //
+//  - If the 'filter' input is provided, corresponding items will be skipped,
+//    and only (repeating `offset`) the next included in the filter will be
+//    returned.
+//
 // Both the list and item must be provided.
 //
 // See also:
@@ -16,7 +20,6 @@
 //
 
 import {input, templateCompositeFrom} from '#composite';
-import {atOffset} from '#sugar';
 
 import {raiseOutputWithoutDependency} from '#composite/control-flow';
 
@@ -28,9 +31,12 @@ export default templateCompositeFrom({
   inputs: {
     list: input({acceptsNull: false, type: 'array'}),
     item: input({acceptsNull: false}),
-
     offset: input({type: 'number'}),
+
     wrap: input({type: 'boolean', defaultValue: false}),
+    valuePastEdge: input({defaultValue: null}),
+
+    filter: input({defaultValue: null, type: 'array'}),
   },
 
   outputs: ['#nearbyItem'],
@@ -45,29 +51,55 @@ export default templateCompositeFrom({
       dependency: '#index',
       mode: input.value('index'),
 
-      output: input.value({
-        ['#nearbyItem']:
-          null,
-      }),
+      output: input.value({'#nearbyItem': null}),
     }),
 
     {
       dependencies: [
         input('list'),
         input('offset'),
+
         input('wrap'),
+        input('valuePastEdge'),
+
+        input('filter'),
+
         '#index',
       ],
 
       compute: (continuation, {
         [input('list')]: list,
         [input('offset')]: offset,
+
         [input('wrap')]: wrap,
+        [input('valuePastEdge')]: valuePastEdge,
+
+        [input('filter')]: filter,
+
         ['#index']: index,
-      }) => continuation({
-        ['#nearbyItem']:
-          atOffset(list, index, offset, {wrap}),
-      }),
+      }) => {
+        const startIndex = index;
+
+        do {
+          index += offset;
+
+          if (wrap) {
+            index = index % list.length;
+          } else if (index < 0) {
+            return continuation({'#nearbyItem': valuePastEdge});
+          } else if (index >= list.length) {
+            return continuation({'#nearbyItem': valuePastEdge});
+          }
+
+          if (filter && !filter[index]) {
+            continue;
+          }
+
+          return continuation({'#nearbyItem': list[index]});
+        } while (index !== startIndex);
+
+        return continuation({'#nearbyItem': null});
+      },
     },
   ],
 });