Skip to content

Commit e52fd36

Browse files
author
Thom
committed
chore: reduce codesmells
1 parent f0c077e commit e52fd36

File tree

5 files changed

+166
-88
lines changed

5 files changed

+166
-88
lines changed

src/ComponentStore/ComponentStore.ts

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -93,51 +93,9 @@ export class ComponentStore<T> {
9393
return cached;
9494
}
9595

96-
for (let p = 0; p < fields.length; p++) {
97-
for (let t = 0; t < oTypes.length; t++) {
98-
const exact = this.lookup(fields[p], oTypes[t], topology);
99-
if (exact !== undefined) {
100-
return this.lookupCache.add(exact, key);
101-
}
102-
}
103-
}
104-
105-
const possibleClasses = this.registeredClasses(fields, topology);
106-
if (possibleClasses.length === 0) {
107-
if (topology === DEFAULT_TOPOLOGY.value) {
108-
return this.lookupCache.add(null, key);
109-
}
110-
const foundComponent = this.getRenderComponent(
111-
oTypes,
112-
fields,
113-
DEFAULT_TOPOLOGY.value,
114-
defaultType,
115-
);
116-
if (!foundComponent) {
117-
return this.lookupCache.add(null, key);
118-
}
96+
const match = this.findMatch(oTypes, fields, topology, defaultType);
11997

120-
return this.lookupCache.add(foundComponent, key);
121-
}
122-
for (let i = 0; i < fields.length; i++) {
123-
const bestClass = this.bestClass(possibleClasses, oTypes);
124-
const component = bestClass && this.lookup(
125-
fields[i],
126-
bestClass,
127-
topology,
128-
);
129-
if (component) {
130-
return this.lookupCache.add(component, key);
131-
}
132-
}
133-
for (let i = 0; i < fields.length; i++) {
134-
const component = this.lookup(fields[i], defaultType, topology);
135-
if (component) {
136-
return this.lookupCache.add(component, key);
137-
}
138-
}
139-
140-
return this.lookupCache.add(null, key);
98+
return this.lookupCache.add(match, key);
14199
}
142100

143101
/**
@@ -219,7 +177,90 @@ export class ComponentStore<T> {
219177
return components.find((c) => chain.indexOf(c) > 0);
220178
}
221179

222-
// interface ComponentMapping<T> { [type: string]: { [obj: string]: { [topology: string]: T } }; }
180+
private classMatch(possibleClasses: Id[], types: Id[], fields: Id[], topology: Id): T | undefined {
181+
for (let i = 0; i < fields.length; i++) {
182+
const bestClass = this.bestClass(possibleClasses, types);
183+
const component = bestClass && this.lookup(
184+
fields[i],
185+
bestClass,
186+
topology,
187+
);
188+
189+
if (component) {
190+
return component;
191+
}
192+
}
193+
194+
return undefined;
195+
}
196+
197+
private defaultMatch(fields: Id[], topology: Id, defaultType: Id): T | undefined {
198+
for (let i = 0; i < fields.length; i++) {
199+
const component = this.lookup(fields[i], defaultType, topology);
200+
if (component) {
201+
return component;
202+
}
203+
}
204+
205+
return undefined;
206+
}
207+
208+
private exactMatch(types: Id[], fields: Id[], topology: Id): T | undefined {
209+
for (let p = 0; p < fields.length; p++) {
210+
for (let t = 0; t < types.length; t++) {
211+
const exact = this.lookup(fields[p], types[t], topology);
212+
if (exact !== undefined) {
213+
return exact;
214+
}
215+
}
216+
}
217+
218+
return undefined;
219+
}
220+
221+
private findMatch(types: Id[], fields: Id[], topology: Id, defaultType: Id): T | null {
222+
let match: T | null | undefined = this.exactMatch(types, fields, topology);
223+
if (match !== undefined) {
224+
return match;
225+
}
226+
227+
const possibleClasses = this.registeredClasses(fields, topology);
228+
229+
if (possibleClasses.length === 0) {
230+
return this.noClassesMatch(types, fields, topology, defaultType);
231+
}
232+
233+
match = this.classMatch(possibleClasses, types, fields, topology);
234+
if (match !== undefined) {
235+
return match;
236+
}
237+
238+
match = this.defaultMatch(fields, topology, defaultType);
239+
if (match !== undefined) {
240+
return match;
241+
}
242+
243+
return null;
244+
}
245+
246+
private noClassesMatch(types: Id[], fields: Id[], topology: Id, defaultType: Id): T | null {
247+
if (topology === DEFAULT_TOPOLOGY.value) {
248+
return null;
249+
}
250+
251+
const foundComponent = this.getRenderComponent(
252+
types,
253+
fields,
254+
DEFAULT_TOPOLOGY.value,
255+
defaultType,
256+
);
257+
258+
if (foundComponent) {
259+
return foundComponent;
260+
}
261+
262+
return null;
263+
}
223264

224265
/**
225266
* Returns a list of classes which have registrations for a combination of {fields} and {topology}.

src/datastrucures/DataSliceDSL.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import rdfFactory, { SomeTerm } from "@ontologies/core";
2+
import { idToValue } from "../factoryHelpers";
23

34
import { SomeNode } from "../types";
45

56
import { DataRecord, DataSlice } from "./DataSlice";
67

8+
export type OptionalIdOrNode = string | SomeNode | undefined;
9+
710
export interface RecordBuilder {
811
/** Sets the {value} of {field} on the current record */
912
field(field: string | SomeNode, value: SomeTerm): this;
@@ -12,11 +15,19 @@ export interface RecordBuilder {
1215
}
1316

1417
export interface SliceBuilder {
15-
record(id?: string | SomeNode | undefined): RecordBuilder;
18+
record(id?: OptionalIdOrNode): RecordBuilder;
1619
}
1720

1821
export type SliceCreator = (slice: SliceBuilder) => void;
1922

23+
const stringIdOrNewLocal = (id: OptionalIdOrNode): string => {
24+
if (id === undefined) {
25+
return rdfFactory.blankNode().value;
26+
}
27+
28+
return typeof id === "string" ? id : id.value;
29+
};
30+
2031
export const buildSlice = (creator: SliceCreator): DataSlice => {
2132
if (creator === undefined) {
2233
throw new Error("No creator passed");
@@ -25,14 +36,9 @@ export const buildSlice = (creator: SliceCreator): DataSlice => {
2536
const slice: DataSlice = {};
2637

2738
const builder: SliceBuilder = {
28-
record(id: string | SomeNode | undefined): RecordBuilder {
29-
const stringId = id === undefined
30-
? rdfFactory.blankNode().value
31-
: (typeof id === "string" ? id : id.value);
32-
33-
const termId = stringId.startsWith("_:")
34-
? rdfFactory.blankNode(stringId)
35-
: rdfFactory.namedNode(stringId);
39+
record(id: OptionalIdOrNode): RecordBuilder {
40+
const stringId = stringIdOrNewLocal(id);
41+
const termId = idToValue(stringId);
3642

3743
const record: DataRecord = {
3844
_id: termId,

src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export {
1919
export { transformers } from "./transformers/index";
2020

2121
export {
22+
OptionalIdOrNode,
2223
SliceCreator,
2324
RecordBuilder,
2425
buildSlice,
@@ -80,6 +81,11 @@ export {
8081
} from "./TypedRecord";
8182
export { RecordState } from "./store/RecordState";
8283
export { RecordStatus } from "./store/RecordStatus";
84+
export {
85+
hasReferenceTo,
86+
fieldReferences,
87+
findAllReferencingIds,
88+
} from "./store/StructuredStore/references";
8389
export {
8490
idField,
8591
StructuredStore,

src/store/StructuredStore.ts

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import rdfFactory, { SomeTerm, TermType } from "@ontologies/core";
1+
import rdfFactory, { SomeTerm } from "@ontologies/core";
22
import * as rdf from "@ontologies/rdf";
33
import * as rdfs from "@ontologies/rdfs";
44

5-
import { DataRecord, FieldSet, Id } from "../datastrucures/DataSlice";
5+
import { DataRecord, DataSlice, FieldSet, Id } from "../datastrucures/DataSlice";
66
import { DeepRecord, DeepRecordFieldValue } from "../datastrucures/DeepSlice";
77
import { FieldId, FieldValue, MultimapTerm } from "../datastrucures/Fields";
88
import { SomeNode } from "../types";
@@ -11,6 +11,7 @@ import { normalizeType } from "../utilities";
1111
import { RecordJournal } from "./RecordJournal";
1212
import { RecordState } from "./RecordState";
1313
import { RecordStatus } from "./RecordStatus";
14+
import { findAllReferencingIds } from "./StructuredStore/references";
1415

1516
export const idField = "_id";
1617
const member = rdfs.member.value;
@@ -79,7 +80,7 @@ export class StructuredStore {
7980
public base: string;
8081

8182
/** @private */
82-
public data: Record<Id, DataRecord>;
83+
public data: DataSlice;
8384

8485
/** @private */
8586
public journal: RecordJournal;
@@ -94,7 +95,7 @@ export class StructuredStore {
9495
*/
9596
constructor(
9697
base: string = "rdf:defaultGraph",
97-
data: Record<Id, DataRecord> | undefined = {},
98+
data: DataSlice | undefined = {},
9899
onChange: (docId: string) => void = (): void => undefined,
99100
) {
100101
this.base = base;
@@ -249,36 +250,7 @@ export class StructuredStore {
249250
* Find all records which reference this given [recordId]
250251
*/
251252
public references(recordId: Id): Id[] {
252-
const references = [];
253-
const data = this.data;
254-
255-
for (const rId in data) {
256-
if (!data.hasOwnProperty(rId)) {
257-
continue;
258-
}
259-
260-
const record = data[rId];
261-
for (const field in record) {
262-
if (!record.hasOwnProperty(field) || field === idField) {
263-
continue;
264-
}
265-
266-
const values = record[field];
267-
if (Array.isArray(values)) {
268-
for (const value of values) {
269-
if (value.termType !== TermType.Literal && value.value === recordId) {
270-
references.push(rId);
271-
}
272-
}
273-
} else {
274-
if (values.termType !== TermType.Literal && values.value === recordId) {
275-
references.push(rId);
276-
}
277-
}
278-
}
279-
}
280-
281-
return references;
253+
return findAllReferencingIds(this.data, recordId);
282254
}
283255

284256
/**
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { TermType } from "@ontologies/core";
2+
3+
import { DataRecord, DataSlice, Id } from "../../datastrucures/DataSlice";
4+
import { FieldValue } from "../../datastrucures/Fields";
5+
import { idField } from "../StructuredStore";
6+
7+
export const fieldReferences = (values: FieldValue, referenced: Id): boolean => {
8+
if (Array.isArray(values)) {
9+
for (const value of values) {
10+
if (value.termType !== TermType.Literal && value.value === referenced) {
11+
return true;
12+
}
13+
}
14+
} else {
15+
if (values.termType !== TermType.Literal && values.value === referenced) {
16+
return true;
17+
}
18+
}
19+
20+
return false;
21+
};
22+
23+
export const hasReferenceTo = (record: DataRecord, referenced: Id): boolean => {
24+
for (const field in record) {
25+
if (!record.hasOwnProperty(field) || field === idField) {
26+
continue;
27+
}
28+
29+
const values = record[field];
30+
if (fieldReferences(values, referenced)) {
31+
return true;
32+
}
33+
}
34+
35+
return false;
36+
};
37+
38+
export const findAllReferencingIds = (data: DataSlice, referenced: Id): Id[] => {
39+
const found = [];
40+
41+
for (const id in data) {
42+
if (!data.hasOwnProperty(id)) {
43+
continue;
44+
}
45+
46+
const record = data[id];
47+
if (hasReferenceTo(record, referenced)) {
48+
found.push(id);
49+
}
50+
}
51+
52+
return found;
53+
};

0 commit comments

Comments
 (0)