@_linked/core 0.0.1 → 1.0.0-next.20260216062729
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/LICENSE +1 -1
- package/README.md +147 -92
- package/lib/cjs/queries/SelectQuery.d.ts +5 -0
- package/lib/cjs/queries/SelectQuery.js +14 -0
- package/lib/cjs/queries/SelectQuery.js.map +1 -1
- package/lib/cjs/shapes/SHACL.d.ts +1 -0
- package/lib/cjs/shapes/SHACL.js +82 -2
- package/lib/cjs/shapes/SHACL.js.map +1 -1
- package/lib/cjs/shapes/Shape.d.ts +13 -1
- package/lib/cjs/shapes/Shape.js +6 -0
- package/lib/cjs/shapes/Shape.js.map +1 -1
- package/lib/cjs/test-helpers/query-fixtures.d.ts +583 -0
- package/lib/cjs/test-helpers/query-fixtures.js +39 -1
- package/lib/cjs/test-helpers/query-fixtures.js.map +1 -1
- package/lib/esm/queries/SelectQuery.d.ts +5 -0
- package/lib/esm/queries/SelectQuery.js +14 -0
- package/lib/esm/queries/SelectQuery.js.map +1 -1
- package/lib/esm/shapes/SHACL.d.ts +1 -0
- package/lib/esm/shapes/SHACL.js +82 -2
- package/lib/esm/shapes/SHACL.js.map +1 -1
- package/lib/esm/shapes/Shape.d.ts +13 -1
- package/lib/esm/shapes/Shape.js +6 -0
- package/lib/esm/shapes/Shape.js.map +1 -1
- package/lib/esm/test-helpers/query-fixtures.d.ts +583 -0
- package/lib/esm/test-helpers/query-fixtures.js +38 -0
- package/lib/esm/test-helpers/query-fixtures.js.map +1 -1
- package/package.json +17 -1
- package/.context/notes.md +0 -0
- package/.context/todos.md +0 -0
- package/AGENTS.md +0 -59
- package/docs/001-core-extraction.md +0 -305
- package/jest.config.js +0 -25
- package/scripts/dual-package.js +0 -25
- package/src/collections/CoreMap.ts +0 -127
- package/src/collections/CoreSet.ts +0 -171
- package/src/collections/ShapeSet.ts +0 -18
- package/src/index.ts +0 -88
- package/src/interfaces/ICoreIterable.ts +0 -35
- package/src/interfaces/IFileStore.ts +0 -28
- package/src/interfaces/IQuadStore.ts +0 -16
- package/src/interfaces/IQueryParser.ts +0 -51
- package/src/ontologies/lincd.ts +0 -25
- package/src/ontologies/npm.ts +0 -15
- package/src/ontologies/owl.ts +0 -26
- package/src/ontologies/rdf.ts +0 -32
- package/src/ontologies/rdfs.ts +0 -38
- package/src/ontologies/shacl.ts +0 -136
- package/src/ontologies/xsd.ts +0 -47
- package/src/package.ts +0 -11
- package/src/queries/CreateQuery.ts +0 -41
- package/src/queries/DeleteQuery.ts +0 -54
- package/src/queries/MutationQuery.ts +0 -287
- package/src/queries/QueryContext.ts +0 -41
- package/src/queries/QueryFactory.ts +0 -275
- package/src/queries/QueryParser.ts +0 -79
- package/src/queries/SelectQuery.ts +0 -2101
- package/src/queries/UpdateQuery.ts +0 -47
- package/src/shapes/List.ts +0 -52
- package/src/shapes/SHACL.ts +0 -653
- package/src/shapes/Shape.ts +0 -282
- package/src/test-helpers/query-fixtures.ts +0 -313
- package/src/tests/core-utils.test.ts +0 -286
- package/src/tests/metadata.test.ts +0 -65
- package/src/tests/query.test.ts +0 -599
- package/src/tests/query.types.test.ts +0 -606
- package/src/tests/store-routing.test.ts +0 -133
- package/src/utils/LinkedErrorLogging.ts +0 -25
- package/src/utils/LinkedFileStorage.ts +0 -75
- package/src/utils/LinkedStorage.ts +0 -120
- package/src/utils/NameSpace.ts +0 -5
- package/src/utils/NodeReference.ts +0 -16
- package/src/utils/Package.ts +0 -681
- package/src/utils/Prefix.ts +0 -108
- package/src/utils/ShapeClass.ts +0 -335
- package/src/utils/Types.ts +0 -19
- package/src/utils/URI.ts +0 -40
- package/src/utils/cached.ts +0 -53
- package/tsconfig-cjs.json +0 -8
- package/tsconfig-esm.json +0 -9
- package/tsconfig.json +0 -29
package/src/utils/Prefix.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
-
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
-
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
-
*/
|
|
6
|
-
import {CoreMap} from '../collections/CoreMap.js';
|
|
7
|
-
|
|
8
|
-
export class Prefix {
|
|
9
|
-
static uriToPrefix: CoreMap<string, string> = new CoreMap();
|
|
10
|
-
static prefixToUri: CoreMap<string, string> = new CoreMap();
|
|
11
|
-
|
|
12
|
-
static getUriToPrefixMap() {
|
|
13
|
-
return this.uriToPrefix;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static getPrefixToUriMap() {
|
|
17
|
-
return this.prefixToUri;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
static add(prefix: string, fullURI: string) {
|
|
21
|
-
this.uriToPrefix.set(fullURI, prefix);
|
|
22
|
-
this.prefixToUri.set(prefix, fullURI);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
static delete(prefix: string) {
|
|
26
|
-
if (this.prefixToUri.has(prefix)) {
|
|
27
|
-
let fullURI = this.getFullURI(prefix);
|
|
28
|
-
this.uriToPrefix.delete(fullURI);
|
|
29
|
-
this.prefixToUri.delete(prefix);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static clear() {
|
|
34
|
-
this.uriToPrefix = new CoreMap<string, string>();
|
|
35
|
-
this.prefixToUri = new CoreMap<string, string>();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
static getPrefix(fullURI: string): string {
|
|
39
|
-
if (this.uriToPrefix.has(fullURI)) {
|
|
40
|
-
return this.uriToPrefix.get(fullURI);
|
|
41
|
-
}
|
|
42
|
-
let match = this.findMatch(fullURI);
|
|
43
|
-
if (match.length > 0) return match[1];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
static getFullURI(prefix: string): string {
|
|
47
|
-
return this.prefixToUri.get(prefix);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
static findMatch(fullURI: string): [string, string, string] | [] {
|
|
52
|
-
for (let [ontologyURI, prefix] of this.uriToPrefix.entries()) {
|
|
53
|
-
if (fullURI.substring(0, ontologyURI.length) == ontologyURI) {
|
|
54
|
-
return [ontologyURI, prefix, fullURI.substring(ontologyURI.length)];
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
static toPrefixed(fullURI: string) {
|
|
61
|
-
let match = this.findMatch(fullURI);
|
|
62
|
-
if (match.length > 0) {
|
|
63
|
-
const postFix = fullURI.substring(match[0].length);
|
|
64
|
-
if (!postFix.includes('/')) {
|
|
65
|
-
return match[1] + ':' + postFix;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
static toPrefixedIfPossible(fullURI: string) {
|
|
71
|
-
return this.toPrefixed(fullURI) || fullURI;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
static toFullIfPossible(fullURI: string): string {
|
|
75
|
-
let res = this._toFull(fullURI);
|
|
76
|
-
if(res) {
|
|
77
|
-
return res;
|
|
78
|
-
}
|
|
79
|
-
return fullURI;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Converts a prefixed URI back to its full URI
|
|
84
|
-
* Will return the prefixed URI if no prefix was found
|
|
85
|
-
* @param uri
|
|
86
|
-
*/
|
|
87
|
-
static toFull(uri) {
|
|
88
|
-
let res = this._toFull(uri);
|
|
89
|
-
if(res) {
|
|
90
|
-
return res;
|
|
91
|
-
}
|
|
92
|
-
let [prefix, rest] = uri.split(':');
|
|
93
|
-
throw new Error(
|
|
94
|
-
'Unknown prefix ' +
|
|
95
|
-
prefix +
|
|
96
|
-
'. Could not convert ' +
|
|
97
|
-
uri +
|
|
98
|
-
' to a full URI',
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
private static _toFull(uri) {
|
|
102
|
-
let [prefix, rest] = uri.split(':');
|
|
103
|
-
let ontologyURI = this.getFullURI(prefix);
|
|
104
|
-
if (ontologyURI) {
|
|
105
|
-
return ontologyURI + rest;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
package/src/utils/ShapeClass.ts
DELETED
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
import {Shape} from '../shapes/Shape.js';
|
|
2
|
-
import {NodeShape, PropertyShape} from '../shapes/SHACL.js';
|
|
3
|
-
import {ICoreIterable} from '../interfaces/ICoreIterable.js';
|
|
4
|
-
import {NodeReferenceValue} from './NodeReference.js';
|
|
5
|
-
|
|
6
|
-
const resolveTargetClassId = (
|
|
7
|
-
targetClass?: NodeReferenceValue | null,
|
|
8
|
-
): string | null => {
|
|
9
|
-
return targetClass?.id ?? null;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
let subShapesSpecificityCache: Map<string, (typeof Shape)[][]> = new Map();
|
|
13
|
-
let subShapesCache: Map<string, (typeof Shape)[]> = new Map();
|
|
14
|
-
let mostSpecificSubShapesCache: Map<string, (typeof Shape)[]> = new Map();
|
|
15
|
-
let nodeShapeToShapeClass: Map<string, typeof Shape> = new Map();
|
|
16
|
-
let shouldResetCache = false;
|
|
17
|
-
|
|
18
|
-
export function addNodeShapeToShapeClass(
|
|
19
|
-
nodeShape: NodeShape,
|
|
20
|
-
shapeClass: typeof Shape,
|
|
21
|
-
) {
|
|
22
|
-
if (!nodeShape?.id) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
nodeShapeToShapeClass.set(nodeShape.id, shapeClass);
|
|
26
|
-
//make sure that the cache is reset after the next event loop
|
|
27
|
-
if (!shouldResetCache) {
|
|
28
|
-
shouldResetCache = true;
|
|
29
|
-
setTimeout(() => {
|
|
30
|
-
subShapesSpecificityCache.clear();
|
|
31
|
-
subShapesCache.clear();
|
|
32
|
-
mostSpecificSubShapesCache.clear();
|
|
33
|
-
shouldResetCache = false;
|
|
34
|
-
}, 0);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function getShapeClass(
|
|
39
|
-
nodeShape: NodeReferenceValue | {id: string} | string,
|
|
40
|
-
): typeof Shape {
|
|
41
|
-
const id = typeof nodeShape === 'string' ? nodeShape : nodeShape?.id;
|
|
42
|
-
if (!id) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
return nodeShapeToShapeClass.get(id);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Returns all the sub shapes of the given shape
|
|
50
|
-
* That is all the shapes that extend this shape
|
|
51
|
-
* @param shape
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
export function getSubShapesClasses(
|
|
55
|
-
shape: typeof Shape | (typeof Shape)[],
|
|
56
|
-
_internalKey?: string,
|
|
57
|
-
): (typeof Shape)[] {
|
|
58
|
-
let key = _internalKey || getKey(shape);
|
|
59
|
-
if (!subShapesCache.has(key)) {
|
|
60
|
-
//make sure we have a real class
|
|
61
|
-
shape = ensureShapeConstructor(shape);
|
|
62
|
-
//apply the hasSuperclass function to the shape
|
|
63
|
-
let filterFunction = applyFnToShapeOrArray(shape, hasSubClass);
|
|
64
|
-
//filter and then sort the results based on their inheritance (most specific classes first, so we use hasSuperClass for the sorting)
|
|
65
|
-
subShapesCache.set(
|
|
66
|
-
key,
|
|
67
|
-
filterShapeClasses(filterFunction).sort((a, b) => {
|
|
68
|
-
return hasSubClass(a, b) ? 1 : -1;
|
|
69
|
-
}),
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
//return a copy of the array to prevent it from being modified
|
|
73
|
-
return [...subShapesCache.get(key)];
|
|
74
|
-
|
|
75
|
-
// let extendsGivenShapeClass = Array.isArray(shape) ? (shapeClass) => {
|
|
76
|
-
// return shape.some(s => shapeClass.constructor.prototype instanceof s);
|
|
77
|
-
// } : (shapeClass) => {
|
|
78
|
-
// return shapeClass.constructor.prototype instanceof shape;
|
|
79
|
-
// }
|
|
80
|
-
//
|
|
81
|
-
// let result = [];
|
|
82
|
-
// nodeShapeToShapeClass.forEach((shapeClass) => {
|
|
83
|
-
// if(extendsGivenShapeClass(shapeClass)) {
|
|
84
|
-
// result.push(shapeClass);
|
|
85
|
-
// }
|
|
86
|
-
// });
|
|
87
|
-
// return result;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Returns all the superclasses of the given shape
|
|
92
|
-
* That is all the shapes that it extends.
|
|
93
|
-
* Results are sorted from most specific to least specific
|
|
94
|
-
* @param shape
|
|
95
|
-
*/
|
|
96
|
-
export function getSuperShapesClasses(
|
|
97
|
-
shape: typeof Shape | (typeof Shape)[],
|
|
98
|
-
): (typeof Shape)[] {
|
|
99
|
-
//make sure we have a real class
|
|
100
|
-
shape = ensureShapeConstructor(shape);
|
|
101
|
-
//apply the hasSuperclass function to the shape
|
|
102
|
-
let filterFunction = applyFnToShapeOrArray(shape, hasSuperClass);
|
|
103
|
-
//filter and then sort the results based on their inheritance
|
|
104
|
-
return filterShapeClasses(filterFunction).sort((a, b) => {
|
|
105
|
-
return hasSubClass(a, b) ? 1 : -1;
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export function getPropertyShapeByLabel(
|
|
110
|
-
shapeClass: typeof Shape,
|
|
111
|
-
label: string,
|
|
112
|
-
): PropertyShape {
|
|
113
|
-
//get all the shapes that this shape extends
|
|
114
|
-
let shapeChain: (typeof Shape)[] = getSuperShapesClasses(
|
|
115
|
-
shapeClass as typeof Shape,
|
|
116
|
-
);
|
|
117
|
-
//include the shape itself as the first shape in the array
|
|
118
|
-
shapeChain.unshift(shapeClass as typeof Shape);
|
|
119
|
-
|
|
120
|
-
let propertyShape: PropertyShape;
|
|
121
|
-
for (let sClass of shapeChain) {
|
|
122
|
-
propertyShape = sClass.shape
|
|
123
|
-
.getPropertyShapes()
|
|
124
|
-
.find((propertyShape) => propertyShape.label === label);
|
|
125
|
-
if (propertyShape) {
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return propertyShape;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
//https://stackoverflow.com/a/30760236
|
|
133
|
-
export function isClass(v) {
|
|
134
|
-
return typeof v === 'function' && /^\s*class\s+/.test(v.toString());
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function ensureShapeConstructor(shape: typeof Shape | (typeof Shape)[]) {
|
|
138
|
-
//TODO: figure out why sometimes we need shape.prototype, sometimes we need shape.constructor.prototype
|
|
139
|
-
// in other words, why we sometimes get a ES6 Class and sometimes its constructor?
|
|
140
|
-
//make sure we have a real class
|
|
141
|
-
|
|
142
|
-
//NOTE: update, this started breaking for when classes are functions. the constructor is native Function
|
|
143
|
-
//had to turn it off for now, waiting for issues to come back up to understand what needs to happen
|
|
144
|
-
return shape;
|
|
145
|
-
// if(Array.isArray(shape))
|
|
146
|
-
// {
|
|
147
|
-
// return shape.map(s => {
|
|
148
|
-
// if (!isClass(s))
|
|
149
|
-
// {
|
|
150
|
-
// return s.constructor as any;
|
|
151
|
-
// }
|
|
152
|
-
// return s;
|
|
153
|
-
// }) as any[];
|
|
154
|
-
// } else {
|
|
155
|
-
// if (!isClass(shape))
|
|
156
|
-
// {
|
|
157
|
-
// return shape.constructor as any;
|
|
158
|
-
// }
|
|
159
|
-
// return shape;
|
|
160
|
-
// }
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export function hasSuperClass(a: Function, b: Function) {
|
|
164
|
-
return (a as Function).prototype instanceof b;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export function hasSubClass(a: Function, b: Function) {
|
|
168
|
-
return (b as Function).prototype instanceof a;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function applyFnToShapeOrArray(shape, filterFn) {
|
|
172
|
-
if (Array.isArray(shape)) {
|
|
173
|
-
return (shapeClass) => {
|
|
174
|
-
//returns true if one of the given shapes extends the shapeClass passed as argument
|
|
175
|
-
return (shape as Function[]).some((s) => filterFn(s, shapeClass));
|
|
176
|
-
};
|
|
177
|
-
} else {
|
|
178
|
-
//first argument will be the given shape class, second argument will be each stored shape class in the map
|
|
179
|
-
//will filter down where the given shape extends the stored shape
|
|
180
|
-
return filterFn.bind(null, shape);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function filterShapeClasses(filterFn) {
|
|
185
|
-
let result = [];
|
|
186
|
-
nodeShapeToShapeClass.forEach((shapeClass) => {
|
|
187
|
-
if (filterFn(shapeClass)) {
|
|
188
|
-
result.push(shapeClass);
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
return result;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function getLeastSpecificShapeClasses(shapes: ICoreIterable<Shape>) {
|
|
195
|
-
let shapeClasses = shapes.map((shape) =>
|
|
196
|
-
getShapeClass(shape.nodeShape.id),
|
|
197
|
-
);
|
|
198
|
-
return filterShapesToLeastSpecific(shapeClasses);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
export function getMostSpecificSubShapes(
|
|
202
|
-
shape: typeof Shape | (typeof Shape)[],
|
|
203
|
-
): (typeof Shape)[] {
|
|
204
|
-
if (!Array.isArray(shape)) {
|
|
205
|
-
shape = [shape];
|
|
206
|
-
}
|
|
207
|
-
//get the subshapes of the given shapes
|
|
208
|
-
let key = shape.map((s) => s.name).join(',');
|
|
209
|
-
if (!mostSpecificSubShapesCache.has(key)) {
|
|
210
|
-
//get the subshapes of the given shapes
|
|
211
|
-
let subShapes: (typeof Shape)[] = getSubShapesClasses(shape, key);
|
|
212
|
-
//filter them down to the most specific ones (that are not extended by any other shape)
|
|
213
|
-
mostSpecificSubShapesCache.set(key, filterShapesToMostSpecific(subShapes));
|
|
214
|
-
}
|
|
215
|
-
return mostSpecificSubShapesCache.get(key);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Filters out all shapes that are extended by any other shape in the given set/array
|
|
220
|
-
* @param subShapes
|
|
221
|
-
*/
|
|
222
|
-
function filterShapesToMostSpecific(subShapes) {
|
|
223
|
-
return subShapes.filter((subShape) => {
|
|
224
|
-
return !subShapes.some((otherSubShape) => {
|
|
225
|
-
return otherSubShape.prototype instanceof subShape;
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Filters out all shapes that extend any other shape in the given set/array
|
|
232
|
-
* @param shapeClasses
|
|
233
|
-
*/
|
|
234
|
-
function filterShapesToLeastSpecific(shapeClasses) {
|
|
235
|
-
return shapeClasses.filter((shapeClass) => {
|
|
236
|
-
return !shapeClasses.some((otherShapeClass) => {
|
|
237
|
-
return (
|
|
238
|
-
otherShapeClass !== shapeClass &&
|
|
239
|
-
shapeClass.prototype instanceof otherShapeClass
|
|
240
|
-
);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Finds the most specific shape class (which extends other shape classes)
|
|
247
|
-
* of all shape classes that this node matches with (that is the node is a valid instance of the shape)
|
|
248
|
-
* And returns an instance of that shape
|
|
249
|
-
* @param property
|
|
250
|
-
* @param shape
|
|
251
|
-
*/
|
|
252
|
-
export function getShapeOrSubShape<S extends Shape = Shape>(
|
|
253
|
-
_node: unknown,
|
|
254
|
-
_shape: typeof Shape | (typeof Shape)[],
|
|
255
|
-
): S {
|
|
256
|
-
throw new Error(
|
|
257
|
-
'getShapeOrSubShape requires RDF node models and is not supported in @_linked/core.',
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export function getMostSpecificShapes(
|
|
262
|
-
_node: unknown,
|
|
263
|
-
_baseShape: typeof Shape | (typeof Shape)[] = Shape,
|
|
264
|
-
): (typeof Shape)[] {
|
|
265
|
-
throw new Error(
|
|
266
|
-
'getMostSpecificShapes requires RDF node models and is not supported in @_linked/core.',
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export function getMostSpecificShapesByType(
|
|
271
|
-
_node: unknown,
|
|
272
|
-
_baseShape: typeof Shape | (typeof Shape)[] = Shape,
|
|
273
|
-
): (typeof Shape)[] {
|
|
274
|
-
throw new Error(
|
|
275
|
-
'getMostSpecificShapesByType requires RDF node models and is not supported in @_linked/core.',
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function getKey(shape: typeof Shape | (typeof Shape)[]) {
|
|
280
|
-
return Array.isArray(shape)
|
|
281
|
-
? shape.map((s) => getShapeKey(s)).join(',')
|
|
282
|
-
: getShapeKey(shape);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
function getShapeKey(shape: typeof Shape) {
|
|
286
|
-
//return a unique string for each shape
|
|
287
|
-
return (
|
|
288
|
-
resolveTargetClassId(shape.targetClass) ||
|
|
289
|
-
shape.name + shape.prototype.constructor.toString().substring(0, 80)
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function getSubShapesClassesSortedBySpecificity(
|
|
294
|
-
baseShape: typeof Shape | (typeof Shape)[] = Shape,
|
|
295
|
-
) {
|
|
296
|
-
let key = getKey(baseShape);
|
|
297
|
-
if (!subShapesSpecificityCache.has(key)) {
|
|
298
|
-
let subShapes: (typeof Shape)[] = getSubShapesClasses(baseShape, key);
|
|
299
|
-
let specificityGroups: (typeof Shape)[][] = [];
|
|
300
|
-
while (subShapes.length > 0) {
|
|
301
|
-
let mostSpecificSubShapes = filterShapesToMostSpecific(subShapes);
|
|
302
|
-
specificityGroups.push(mostSpecificSubShapes);
|
|
303
|
-
mostSpecificSubShapes.forEach((mostSpecificSubShape) => {
|
|
304
|
-
subShapes.splice(subShapes.indexOf(mostSpecificSubShape), 1);
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
subShapesSpecificityCache.set(key, specificityGroups);
|
|
308
|
-
}
|
|
309
|
-
return subShapesSpecificityCache.get(key);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function _getMostSpecificShapes(
|
|
313
|
-
baseShape: typeof Shape | (typeof Shape)[] = Shape,
|
|
314
|
-
shapeValidationFn,
|
|
315
|
-
) {
|
|
316
|
-
//get the subshapes of the given base shape(s)
|
|
317
|
-
let subShapes = getSubShapesClassesSortedBySpecificity(baseShape);
|
|
318
|
-
|
|
319
|
-
let res;
|
|
320
|
-
//for each group of most specific subshapes (before going to the next group of less specific subshapes)
|
|
321
|
-
for (let subShapeGroup of subShapes) {
|
|
322
|
-
//filter them down to the ones that this node is a valid instance of
|
|
323
|
-
let shapesThatMatchNode = subShapeGroup.filter(shapeValidationFn); //if any of them can create a valid instance for this node, then return that
|
|
324
|
-
|
|
325
|
-
//if any of them can create a valid instance for this node, then return that
|
|
326
|
-
if (shapesThatMatchNode.length > 0) {
|
|
327
|
-
res = shapesThatMatchNode;
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
if (!res) {
|
|
332
|
-
res = [];
|
|
333
|
-
}
|
|
334
|
-
return res;
|
|
335
|
-
}
|
package/src/utils/Types.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A type that represents a class constructor
|
|
3
|
-
*/
|
|
4
|
-
export type ClassOf<B> = new (...args: any[]) => B;
|
|
5
|
-
/**
|
|
6
|
-
* A type that represents an instance of a class (class being a type which is created with ClassOf)
|
|
7
|
-
*/
|
|
8
|
-
export type InstanceOf<B extends ClassOf<any>> =
|
|
9
|
-
B extends ClassOf<infer C> ? C : never;
|
|
10
|
-
|
|
11
|
-
export type Not<T extends boolean> = T extends true ? false : true;
|
|
12
|
-
|
|
13
|
-
export type Or<A, B> = A extends true ? true : B extends true ? true : false;
|
|
14
|
-
|
|
15
|
-
export type And<A, B> = A extends true
|
|
16
|
-
? B extends true
|
|
17
|
-
? true
|
|
18
|
-
: false
|
|
19
|
-
: false;
|
package/src/utils/URI.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
-
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
-
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
-
*/
|
|
6
|
-
export class URI {
|
|
7
|
-
/**
|
|
8
|
-
* Function: sanitize
|
|
9
|
-
* Returns a sanitized string, typically for URLs.
|
|
10
|
-
*
|
|
11
|
-
* Parameters:
|
|
12
|
-
* $string - The string to sanitize.
|
|
13
|
-
* $force_lowercase - Force the string to lowercase?
|
|
14
|
-
*/
|
|
15
|
-
static sanitize(string) {
|
|
16
|
-
if (!string) return string;
|
|
17
|
-
//\u200B is the ZERO WIDTH SPACE, often introduced by WYSIWYG editors. This causes a hyphen (-) at the end of a string sometimes, so we filter it out first
|
|
18
|
-
return string
|
|
19
|
-
.replace(/\u200B/g, '')
|
|
20
|
-
.replace(/[^\w]+/g, '-')
|
|
21
|
-
.toLowerCase();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
static isURI(uri: string) {
|
|
25
|
-
//must have a scheme followed by ://
|
|
26
|
-
return /([A-Za-z][A-Za-z0-9+\-.]*)\:\/\//.test(uri);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Generate a new URI based on the given URI components (labels / identifiers).
|
|
31
|
-
* This URI will start with the DATA_ROOT environment variable
|
|
32
|
-
* @param uriComponents
|
|
33
|
-
*/
|
|
34
|
-
static generate(...uriComponents: string[]) {
|
|
35
|
-
return (
|
|
36
|
-
process.env.DATA_ROOT +
|
|
37
|
-
uriComponents.filter(Boolean).map(encodeURIComponent).join('/')
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
}
|
package/src/utils/cached.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import {Shape} from '../shapes/Shape.js';
|
|
2
|
-
|
|
3
|
-
const _cache = new Map<string, {timeout: number; value: any}>();
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Caches the result of a function call based on its arguments for a specified time.
|
|
7
|
-
* Arguments are converted to strings for comparison.
|
|
8
|
-
* Use cacheTimeMs = 0 to disable caching.
|
|
9
|
-
* Use cacheTimeMs = Infinity to never expire the cache.
|
|
10
|
-
* @param fn
|
|
11
|
-
* @param args
|
|
12
|
-
* @param cacheTimeMs
|
|
13
|
-
* @param alsoCacheErrors
|
|
14
|
-
*/
|
|
15
|
-
export function cached(fn: () => any, args: any[], cacheTimeMs?: number,alsoCacheErrors?: boolean) {
|
|
16
|
-
if (cacheTimeMs !== 0) {
|
|
17
|
-
const now = Date.now();
|
|
18
|
-
args = args.map((a) => {
|
|
19
|
-
if (a instanceof Shape) {
|
|
20
|
-
return a.id ?? a.uri;
|
|
21
|
-
} else if (a && typeof a === 'object' && 'id' in a) {
|
|
22
|
-
return (a as {id: string}).id;
|
|
23
|
-
} else {
|
|
24
|
-
return a?.toString();
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
let key = JSON.stringify(args);
|
|
28
|
-
let cache = _cache.get(key);
|
|
29
|
-
if (cache && cache.timeout < now) {
|
|
30
|
-
_cache.delete(key);
|
|
31
|
-
cache = null;
|
|
32
|
-
}
|
|
33
|
-
if (!cache) {
|
|
34
|
-
let value;
|
|
35
|
-
try {
|
|
36
|
-
value = fn();
|
|
37
|
-
} catch(e) {
|
|
38
|
-
if(alsoCacheErrors) {
|
|
39
|
-
value = e;
|
|
40
|
-
} else {
|
|
41
|
-
throw e;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
_cache.set(key, {
|
|
45
|
-
timeout: now + cacheTimeMs,
|
|
46
|
-
value,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return _cache.get(key).value;
|
|
50
|
-
} else {
|
|
51
|
-
return fn();
|
|
52
|
-
}
|
|
53
|
-
}
|
package/tsconfig-cjs.json
DELETED
package/tsconfig-esm.json
DELETED
package/tsconfig.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"sourceMap": true,
|
|
4
|
-
"declaration": true,
|
|
5
|
-
"experimentalDecorators": true,
|
|
6
|
-
"emitDecoratorMetadata": true,
|
|
7
|
-
"downlevelIteration": true,
|
|
8
|
-
"resolveJsonModule": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"pretty": true,
|
|
12
|
-
"target": "es6",
|
|
13
|
-
"jsx": "react",
|
|
14
|
-
"moduleResolution": "node",
|
|
15
|
-
"types": ["node", "jest"],
|
|
16
|
-
"baseUrl": "./",
|
|
17
|
-
"paths": {
|
|
18
|
-
"*": ["node_modules/@types/*", "../../node_modules/@types/*", "*"]
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"include": [
|
|
22
|
-
"./src/**/*.ts",
|
|
23
|
-
"./src/**/*.tsx",
|
|
24
|
-
"../node_modules/ts-jest/globals.d.ts"
|
|
25
|
-
],
|
|
26
|
-
"exclude": [
|
|
27
|
-
"./src/tests/**"
|
|
28
|
-
]
|
|
29
|
-
}
|