« get me outta code hell

data: break up content.js, flash.js, sorting-rule.js - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/content
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2026-01-26 14:07:13 -0400
committer(quasar) nebula <qznebula@protonmail.com>2026-01-26 14:07:13 -0400
commit1f37e5d6b0c6fccc9c46aabd7bd402375131d452 (patch)
treee441757a73dd2b2cb346ce33b90bf185c614fe7c /src/data/things/content
parentaa3cb2dd34780fd97873340c3faf7388993fa8d8 (diff)
data: break up content.js, flash.js, sorting-rule.js
Diffstat (limited to 'src/data/things/content')
-rw-r--r--src/data/things/content/CommentaryEntry.js20
-rw-r--r--src/data/things/content/ContentEntry.js246
-rw-r--r--src/data/things/content/CreditingSourcesEntry.js16
-rw-r--r--src/data/things/content/LyricsEntry.js43
-rw-r--r--src/data/things/content/ReferencingSourcesEntry.js16
-rw-r--r--src/data/things/content/index.js9
6 files changed, 350 insertions, 0 deletions
diff --git a/src/data/things/content/CommentaryEntry.js b/src/data/things/content/CommentaryEntry.js
new file mode 100644
index 00000000..32d69213
--- /dev/null
+++ b/src/data/things/content/CommentaryEntry.js
@@ -0,0 +1,20 @@
+import {V} from '#composite';
+import Thing from '#thing';
+
+import {exposeConstant} from '#composite/control-flow';
+
+import {hasAnnotationPart} from '#composite/things/content';
+
+import {ContentEntry} from './ContentEntry.js';
+
+export class CommentaryEntry extends ContentEntry {
+  static [Thing.wikiData] = 'commentaryData';
+
+  static [Thing.getPropertyDescriptors] = () => ({
+    // Expose only
+
+    isCommentaryEntry: exposeConstant(V(true)),
+
+    isWikiEditorCommentary: hasAnnotationPart(V('wiki editor')),
+  });
+}
diff --git a/src/data/things/content/ContentEntry.js b/src/data/things/content/ContentEntry.js
new file mode 100644
index 00000000..7dc81345
--- /dev/null
+++ b/src/data/things/content/ContentEntry.js
@@ -0,0 +1,246 @@
+import {input, V} from '#composite';
+import {transposeArrays} from '#sugar';
+import Thing from '#thing';
+import {is, isDate, validateReferenceList} from '#validators';
+import {parseDate} from '#yaml';
+
+import {withFilteredList, withMappedList, withPropertyFromList}
+  from '#composite/data';
+import {withResolvedReferenceList} from '#composite/wiki-data';
+import {contentString, simpleDate, soupyFind, thing}
+  from '#composite/wiki-properties';
+
+import {
+  exitWithoutDependency,
+  exposeConstant,
+  exposeDependency,
+  exposeDependencyOrContinue,
+  exposeUpdateValueOrContinue,
+  withResultOfAvailabilityCheck,
+} from '#composite/control-flow';
+
+import {
+  withAnnotationPartNodeLists,
+  withExpressedOrImplicitArtistReferences,
+  withWebArchiveDate,
+} from '#composite/things/content';
+
+export class ContentEntry extends Thing {
+  static [Thing.getPropertyDescriptors] = () => ({
+    // Update & expose
+
+    thing: thing(),
+
+    artists: [
+      withExpressedOrImplicitArtistReferences({
+        from: input.updateValue({
+          validate: validateReferenceList('artist'),
+        }),
+      }),
+
+      exitWithoutDependency('#artistReferences', V([])),
+
+      withResolvedReferenceList({
+        list: '#artistReferences',
+        find: soupyFind.input('artist'),
+      }),
+
+      exposeDependency('#resolvedReferenceList'),
+    ],
+
+    artistText: contentString(),
+
+    annotation: contentString(),
+
+    dateKind: {
+      flags: {update: true, expose: true},
+
+      update: {
+        validate: is(...[
+          'sometime',
+          'throughout',
+          'around',
+        ]),
+      },
+    },
+
+    accessKind: [
+      exitWithoutDependency('_accessDate'),
+
+      exposeUpdateValueOrContinue({
+        validate: input.value(
+          is(...[
+            'captured',
+            'accessed',
+          ])),
+      }),
+
+      withWebArchiveDate(),
+
+      withResultOfAvailabilityCheck({from: '#webArchiveDate'}),
+
+      {
+        dependencies: ['#availability'],
+        compute: (continuation, {['#availability']: availability}) =>
+          (availability
+            ? continuation.exit('captured')
+            : continuation()),
+      },
+
+      exposeConstant(V('accessed')),
+    ],
+
+    date: simpleDate(),
+    secondDate: simpleDate(),
+
+    accessDate: [
+      exposeUpdateValueOrContinue({
+        validate: input.value(isDate),
+      }),
+
+      withWebArchiveDate(),
+
+      exposeDependencyOrContinue({
+        dependency: '#webArchiveDate',
+      }),
+
+      exposeConstant(V(null)),
+    ],
+
+    body: contentString(),
+
+    // Update only
+
+    find: soupyFind(),
+
+    // Expose only
+
+    isContentEntry: exposeConstant(V(true)),
+
+    annotationParts: [
+      withAnnotationPartNodeLists(),
+
+      {
+        dependencies: ['#annotationPartNodeLists'],
+        compute: (continuation, {
+          ['#annotationPartNodeLists']: nodeLists,
+        }) => continuation({
+          ['#firstNodes']:
+            nodeLists.map(list => list.at(0)),
+
+          ['#lastNodes']:
+            nodeLists.map(list => list.at(-1)),
+        }),
+      },
+
+      withPropertyFromList('#firstNodes', V('i'))
+        .outputs({'#firstNodes.i': '#startIndices'}),
+
+      withPropertyFromList('#lastNodes', V('iEnd'))
+        .outputs({'#lastNodes.iEnd': '#endIndices'}),
+
+      {
+        dependencies: [
+          'annotation',
+          '#startIndices',
+          '#endIndices',
+        ],
+
+        compute: ({
+          ['annotation']: annotation,
+          ['#startIndices']: startIndices,
+          ['#endIndices']: endIndices,
+        }) =>
+          transposeArrays([startIndices, endIndices])
+            .map(([start, end]) =>
+              annotation.slice(start, end)),
+      },
+    ],
+
+    sourceText: [
+      withAnnotationPartNodeLists(),
+
+      {
+        dependencies: ['#annotationPartNodeLists'],
+        compute: (continuation, {
+          ['#annotationPartNodeLists']: nodeLists,
+        }) => continuation({
+          ['#firstPartWithExternalLink']:
+            nodeLists
+              .find(nodes => nodes
+                .some(node => node.type === 'external-link')) ??
+            null,
+        }),
+      },
+
+      exitWithoutDependency('#firstPartWithExternalLink'),
+
+      {
+        dependencies: ['annotation', '#firstPartWithExternalLink'],
+        compute: ({
+          ['annotation']: annotation,
+          ['#firstPartWithExternalLink']: nodes,
+        }) =>
+          annotation.slice(
+            nodes.at(0).i,
+            nodes.at(-1).iEnd),
+      },
+    ],
+
+    sourceURLs: [
+      withAnnotationPartNodeLists(),
+
+      {
+        dependencies: ['#annotationPartNodeLists'],
+        compute: (continuation, {
+          ['#annotationPartNodeLists']: nodeLists,
+        }) => continuation({
+          ['#firstPartWithExternalLink']:
+            nodeLists
+              .find(nodes => nodes
+                .some(node => node.type === 'external-link')) ??
+            null,
+        }),
+      },
+
+      exitWithoutDependency('#firstPartWithExternalLink', V([])),
+
+      withMappedList({
+        list: '#firstPartWithExternalLink',
+        map: input.value(node => node.type === 'external-link'),
+      }).outputs({
+        '#mappedList': '#externalLinkFilter',
+      }),
+
+      withFilteredList({
+        list: '#firstPartWithExternalLink',
+        filter: '#externalLinkFilter',
+      }),
+
+      withMappedList({
+        list: '#filteredList',
+        map: input.value(node => node.data.href),
+      }),
+
+      exposeDependency('#mappedList'),
+    ],
+  });
+
+  static [Thing.yamlDocumentSpec] = {
+    fields: {
+      'Artists': {property: 'artists'},
+      'Artist Text': {property: 'artistText'},
+
+      'Annotation': {property: 'annotation'},
+
+      'Date Kind': {property: 'dateKind'},
+      'Access Kind': {property: 'accessKind'},
+
+      'Date': {property: 'date', transform: parseDate},
+      'Second Date': {property: 'secondDate', transform: parseDate},
+      'Access Date': {property: 'accessDate', transform: parseDate},
+
+      'Body': {property: 'body'},
+    },
+  };
+}
diff --git a/src/data/things/content/CreditingSourcesEntry.js b/src/data/things/content/CreditingSourcesEntry.js
new file mode 100644
index 00000000..7331ae8c
--- /dev/null
+++ b/src/data/things/content/CreditingSourcesEntry.js
@@ -0,0 +1,16 @@
+import {V} from '#composite';
+import Thing from '#thing';
+
+import {exposeConstant} from '#composite/control-flow';
+
+import {ContentEntry} from './ContentEntry.js';
+
+export class CreditingSourcesEntry extends ContentEntry {
+  static [Thing.wikiData] = 'creditingSourceData';
+
+  static [Thing.getPropertyDescriptors] = () => ({
+    // Expose only
+
+    isCreditingSourcesEntry: exposeConstant(V(true)),
+  });
+}
diff --git a/src/data/things/content/LyricsEntry.js b/src/data/things/content/LyricsEntry.js
new file mode 100644
index 00000000..88e4464d
--- /dev/null
+++ b/src/data/things/content/LyricsEntry.js
@@ -0,0 +1,43 @@
+import {V} from '#composite';
+import Thing from '#thing';
+
+import {exitWithoutDependency, exposeConstant} from '#composite/control-flow';
+import {contentString} from '#composite/wiki-properties';
+
+import {hasAnnotationPart} from '#composite/things/content';
+
+import {ContentEntry} from './ContentEntry.js';
+
+export class LyricsEntry extends ContentEntry {
+  static [Thing.wikiData] = 'lyricsData';
+
+  static [Thing.getPropertyDescriptors] = () => ({
+    // Update & expose
+
+    originDetails: contentString(),
+
+    // Expose only
+
+    isLyricsEntry: exposeConstant(V(true)),
+
+    isWikiLyrics: hasAnnotationPart(V('wiki lyrics')),
+    helpNeeded: hasAnnotationPart(V('help needed')),
+
+    hasSquareBracketAnnotations: [
+      exitWithoutDependency('isWikiLyrics', V(false), V('falsy')),
+      exitWithoutDependency('body', V(false)),
+
+      {
+        dependencies: ['body'],
+        compute: ({body}) =>
+          /\[.*\]/m.test(body),
+      },
+    ],
+  });
+
+  static [Thing.yamlDocumentSpec] = Thing.extendDocumentSpec(ContentEntry, {
+    fields: {
+      'Origin Details': {property: 'originDetails'},
+    },
+  });
+}
diff --git a/src/data/things/content/ReferencingSourcesEntry.js b/src/data/things/content/ReferencingSourcesEntry.js
new file mode 100644
index 00000000..76fafbc2
--- /dev/null
+++ b/src/data/things/content/ReferencingSourcesEntry.js
@@ -0,0 +1,16 @@
+import {V} from '#composite';
+import Thing from '#thing';
+
+import {exposeConstant} from '#composite/control-flow';
+
+import {ContentEntry} from './ContentEntry.js';
+
+export class ReferencingSourcesEntry extends ContentEntry {
+  static [Thing.wikiData] = 'referencingSourceData';
+
+  static [Thing.getPropertyDescriptors] = () => ({
+    // Expose only
+
+    isReferencingSourceEntry: exposeConstant(V(true)),
+  });
+}
diff --git a/src/data/things/content/index.js b/src/data/things/content/index.js
new file mode 100644
index 00000000..aaa7f304
--- /dev/null
+++ b/src/data/things/content/index.js
@@ -0,0 +1,9 @@
+// Yet Another Index.js File Descending From A Folder Named Content
+
+export * from './ContentEntry.js';
+
+export * from './CommentaryEntry.js';
+export * from './LyricsEntry.js';
+
+export * from './CreditingSourcesEntry.js';
+export * from './ReferencingSourcesEntry.js';