« get me outta code hell

data, infra: actually sort subclasses after superclasses - 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-11-19 22:32:34 -0400
committer(quasar) nebula <qznebula@protonmail.com>2025-11-25 07:06:48 -0400
commit0b963b6e6b4f90c80e7369a804407f32e69c7ede (patch)
tree0800c0a81ae0a72d6f319eb3315367d6baffc8d4 /src
parentc7b7a42caab402b5ca1e6d236c4ed9d70f5bf5f3 (diff)
data, infra: actually sort subclasses after superclasses
critically necessary for literally any inheritence shenanigans
Diffstat (limited to 'src')
-rw-r--r--src/data/things/index.js42
1 files changed, 28 insertions, 14 deletions
diff --git a/src/data/things/index.js b/src/data/things/index.js
index 11307b50..41301575 100644
--- a/src/data/things/index.js
+++ b/src/data/things/index.js
@@ -6,7 +6,7 @@ import CacheableObject from '#cacheable-object';
 import {logError} from '#cli';
 import {compositeFrom} from '#composite';
 import * as serialize from '#serialize';
-import {withEntries} from '#sugar';
+import {empty} from '#sugar';
 import Thing from '#thing';
 
 import * as additionalFileClasses from './additional-file.js';
@@ -90,25 +90,39 @@ function errorDuplicateClassNames() {
 }
 
 function flattenClassLists() {
-  let allClassesUnsorted = Object.create(null);
-
+  let remaining = [];
   for (const classes of Object.values(allClassLists)) {
-    for (const [name, constructor] of Object.entries(classes)) {
+    for (const constructor of Object.values(classes)) {
       if (typeof constructor !== 'function') continue;
       if (!(constructor.prototype instanceof Thing)) continue;
-      allClassesUnsorted[name] = constructor;
+      remaining.push(constructor);
     }
   }
 
-  // Sort subclasses after their superclasses.
-  Object.assign(allClasses,
-    withEntries(allClassesUnsorted, entries =>
-      entries.sort(({[1]: A}, {[1]: B}) =>
-        (A.prototype instanceof B
-          ? +1
-       : B.prototype instanceof A
-          ? -1
-          :  0))));
+  let sorted = [];
+  while (true) {
+    if (sorted[0]) {
+      const superclass = Object.getPrototypeOf(sorted[0]);
+      if (superclass !== Thing) {
+        if (sorted.includes(superclass)) {
+          sorted.unshift(...sorted.splice(sorted.indexOf(superclass), 1));
+        } else {
+          sorted.unshift(superclass);
+        }
+        continue;
+      }
+    }
+
+    if (!empty(remaining)) {
+      sorted.unshift(remaining.shift());
+    } else {
+      break;
+    }
+  }
+
+  for (const constructor of sorted) {
+    allClasses[constructor.name] = constructor;
+  }
 }
 
 function descriptorAggregateHelper({