]> Lady’s Gitweb - Etiquette/blob - schema.js
Apply some reformatting and make Reuse‐compliant
[Etiquette] / schema.js
1 // SPDX-FileCopyrightText: 2023, 2025 Lady <https://www.ladys.computer/about/#lady>
2 // SPDX-License-Identifier: MPL-2.0
3 /**
4 * ⁌ 📧🏷️ Étiquette ∷ schema.js
5 *
6 * Copyright © 2023, 2025 Lady [@ Ladys Computer].
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
11 */
12
13 // ※ The definitions in this file are minimal and only really geared
14 // towards supporting the functionality that 📧🏷️ Étiquette needs.
15
16 /**
17 * Supported class types.
18 *
19 * The class `"Thing"´ is not defined, but is used as a generic
20 * superclass.
21 */
22 const classes = {
23 Tag: { subClassOf: "Thing" },
24 CanonTag: { subClassOf: "Tag" },
25 ConceptualTag: { subClassOf: "Tag" },
26 RelationshipTag: {
27 subClassOf: ["ConceptualTag", {
28 onProperty: "involves",
29 allValuesFrom: {
30 unionOf: ["CharacterTag", "RelationshipTag"],
31 },
32 }],
33 },
34 FriendshipTag: { subClassOf: "RelationshipTag" },
35 RivalryTag: { subClassOf: "RelationshipTag" },
36 FamilialRelationshipTag: { subClassOf: "RelationshipTag" },
37 RomanticRelationshipTag: { subClassOf: "RelationshipTag" },
38 SexualRelationshipTag: { subClassOf: "RelationshipTag" },
39 EntityTag: { subClassOf: "Tag" },
40 CharacterTag: { subClassOf: "EntityTag" },
41 InanimateEntityTag: { subClassOf: "EntityTag" },
42 GenreTag: { subClassOf: "Tag" },
43 SettingTag: { subClassOf: "Tag" },
44 LocationTag: { subClassOf: "SettingTag" },
45 TimePeriodTag: { subClassOf: "SettingTag" },
46 UniverseTag: { subClassOf: "SettingTag" },
47 };
48
49 /** Supported transitive object properties. */
50 const transitiveProperties = {
51 broaderTransitive: { domain: "Tag", range: "Tag" },
52 narrowerTransitive: { inverseOf: "broaderTransitive" },
53 };
54
55 /** Supported object properties. */
56 const objectProperties = {
57 broader: { subPropertyOf: "broaderTransitive" },
58 narrower: {
59 inverseOf: "broader",
60 subPropertyOf: "narrowerTransitive",
61 },
62 inCanon: {
63 domain: { unionOf: ["EntityTag", "SettingTag"] },
64 range: "CanonTag",
65 },
66 hasInCanon: { inverseOf: "inCanon" },
67 involves: { domain: "ConceptualTag", range: "Tag" },
68 involvedIn: { inverseOf: "involves" },
69 ...transitiveProperties,
70 };
71
72 /** Supported data properties. */
73 const dataProperties = {
74 prefLabel: { domain: "Thing", range: "PlainLiteral" },
75 altLabel: { domain: "Thing", range: "PlainLiteral" },
76 hiddenLabel: { domain: "Thing", range: "PlainLiteral" },
77 };
78
79 /**
80 * Returns an immutable, null‐prototype object deeply derived from the
81 * provided one.
82 *
83 * ※ Once records and tuples are added to Ecmascript, the schema
84 * should be defined in terms of those primitives. In the meantime,
85 * this function at least ensures the schema is Very Immutable.
86 */
87 const makeRecord = ($) => {
88 return Object.preventExtensions(
89 Object.create(
90 null,
91 Object.fromEntries([...function* () {
92 for (const [key, value] of Object.entries($)) {
93 if (Object(value) === value) {
94 const recordValue = makeRecord(value);
95 yield [key, { enumerable: true, value: recordValue }];
96 } else {
97 yield [key, { enumerable: true, value }];
98 }
99 }
100 if (Array.isArray($)) {
101 yield ["length", { value: $.length }];
102 } else {
103 /* do nothing */
104 }
105 }()]),
106 ),
107 );
108 };
109
110 export default makeRecord({
111 classes,
112 objectProperties,
113 transitiveProperties,
114 dataProperties,
115 });
This page took 0.056948 seconds and 5 git commands to generate.