@_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.
Files changed (81) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/LICENSE +1 -1
  3. package/README.md +147 -92
  4. package/lib/cjs/queries/SelectQuery.d.ts +5 -0
  5. package/lib/cjs/queries/SelectQuery.js +14 -0
  6. package/lib/cjs/queries/SelectQuery.js.map +1 -1
  7. package/lib/cjs/shapes/SHACL.d.ts +1 -0
  8. package/lib/cjs/shapes/SHACL.js +82 -2
  9. package/lib/cjs/shapes/SHACL.js.map +1 -1
  10. package/lib/cjs/shapes/Shape.d.ts +13 -1
  11. package/lib/cjs/shapes/Shape.js +6 -0
  12. package/lib/cjs/shapes/Shape.js.map +1 -1
  13. package/lib/cjs/test-helpers/query-fixtures.d.ts +583 -0
  14. package/lib/cjs/test-helpers/query-fixtures.js +39 -1
  15. package/lib/cjs/test-helpers/query-fixtures.js.map +1 -1
  16. package/lib/esm/queries/SelectQuery.d.ts +5 -0
  17. package/lib/esm/queries/SelectQuery.js +14 -0
  18. package/lib/esm/queries/SelectQuery.js.map +1 -1
  19. package/lib/esm/shapes/SHACL.d.ts +1 -0
  20. package/lib/esm/shapes/SHACL.js +82 -2
  21. package/lib/esm/shapes/SHACL.js.map +1 -1
  22. package/lib/esm/shapes/Shape.d.ts +13 -1
  23. package/lib/esm/shapes/Shape.js +6 -0
  24. package/lib/esm/shapes/Shape.js.map +1 -1
  25. package/lib/esm/test-helpers/query-fixtures.d.ts +583 -0
  26. package/lib/esm/test-helpers/query-fixtures.js +38 -0
  27. package/lib/esm/test-helpers/query-fixtures.js.map +1 -1
  28. package/package.json +17 -1
  29. package/.context/notes.md +0 -0
  30. package/.context/todos.md +0 -0
  31. package/AGENTS.md +0 -59
  32. package/docs/001-core-extraction.md +0 -305
  33. package/jest.config.js +0 -25
  34. package/scripts/dual-package.js +0 -25
  35. package/src/collections/CoreMap.ts +0 -127
  36. package/src/collections/CoreSet.ts +0 -171
  37. package/src/collections/ShapeSet.ts +0 -18
  38. package/src/index.ts +0 -88
  39. package/src/interfaces/ICoreIterable.ts +0 -35
  40. package/src/interfaces/IFileStore.ts +0 -28
  41. package/src/interfaces/IQuadStore.ts +0 -16
  42. package/src/interfaces/IQueryParser.ts +0 -51
  43. package/src/ontologies/lincd.ts +0 -25
  44. package/src/ontologies/npm.ts +0 -15
  45. package/src/ontologies/owl.ts +0 -26
  46. package/src/ontologies/rdf.ts +0 -32
  47. package/src/ontologies/rdfs.ts +0 -38
  48. package/src/ontologies/shacl.ts +0 -136
  49. package/src/ontologies/xsd.ts +0 -47
  50. package/src/package.ts +0 -11
  51. package/src/queries/CreateQuery.ts +0 -41
  52. package/src/queries/DeleteQuery.ts +0 -54
  53. package/src/queries/MutationQuery.ts +0 -287
  54. package/src/queries/QueryContext.ts +0 -41
  55. package/src/queries/QueryFactory.ts +0 -275
  56. package/src/queries/QueryParser.ts +0 -79
  57. package/src/queries/SelectQuery.ts +0 -2101
  58. package/src/queries/UpdateQuery.ts +0 -47
  59. package/src/shapes/List.ts +0 -52
  60. package/src/shapes/SHACL.ts +0 -653
  61. package/src/shapes/Shape.ts +0 -282
  62. package/src/test-helpers/query-fixtures.ts +0 -313
  63. package/src/tests/core-utils.test.ts +0 -286
  64. package/src/tests/metadata.test.ts +0 -65
  65. package/src/tests/query.test.ts +0 -599
  66. package/src/tests/query.types.test.ts +0 -606
  67. package/src/tests/store-routing.test.ts +0 -133
  68. package/src/utils/LinkedErrorLogging.ts +0 -25
  69. package/src/utils/LinkedFileStorage.ts +0 -75
  70. package/src/utils/LinkedStorage.ts +0 -120
  71. package/src/utils/NameSpace.ts +0 -5
  72. package/src/utils/NodeReference.ts +0 -16
  73. package/src/utils/Package.ts +0 -681
  74. package/src/utils/Prefix.ts +0 -108
  75. package/src/utils/ShapeClass.ts +0 -335
  76. package/src/utils/Types.ts +0 -19
  77. package/src/utils/URI.ts +0 -40
  78. package/src/utils/cached.ts +0 -53
  79. package/tsconfig-cjs.json +0 -8
  80. package/tsconfig-esm.json +0 -9
  81. package/tsconfig.json +0 -29
@@ -1,133 +0,0 @@
1
- import {describe, expect, test} from '@jest/globals';
2
- import {linkedPackage} from '../utils/Package';
3
- import {Shape} from '../shapes/Shape';
4
- import {LinkedStorage} from '../utils/LinkedStorage';
5
- import {IQuadStore} from '../interfaces/IQuadStore';
6
- import {NodeReferenceValue} from '../utils/NodeReference';
7
-
8
- const {linkedShape} = linkedPackage('store-routing-test');
9
-
10
- const type = (suffix: string): NodeReferenceValue => ({
11
- id: `linked://tmp/types/${suffix}`,
12
- });
13
-
14
- @linkedShape
15
- class RoutedPerson extends Shape {
16
- static targetClass = type('RoutedPerson');
17
- }
18
-
19
- @linkedShape
20
- class RoutedEmployee extends RoutedPerson {
21
- static targetClass = type('RoutedEmployee');
22
- }
23
-
24
- @linkedShape
25
- class RoutedPet extends Shape {
26
- static targetClass = type('RoutedPet');
27
- }
28
-
29
- type StoreCalls = {
30
- select: number;
31
- update: number;
32
- create: number;
33
- delete: number;
34
- };
35
-
36
- const createStore = () => {
37
- const calls: StoreCalls = {select: 0, update: 0, create: 0, delete: 0};
38
- const store: IQuadStore = {
39
- selectQuery: async <ResultType>() => {
40
- calls.select += 1;
41
- return [] as ResultType;
42
- },
43
- updateQuery: async () => {
44
- calls.update += 1;
45
- return {} as any;
46
- },
47
- createQuery: async () => {
48
- calls.create += 1;
49
- return {} as any;
50
- },
51
- deleteQuery: async () => {
52
- calls.delete += 1;
53
- return {deleted: [], count: 0};
54
- },
55
- };
56
- return {store, calls};
57
- };
58
-
59
- describe('LinkedStorage store routing', () => {
60
- test('routes select queries based on shape mapping', async () => {
61
- const defaultStore = createStore();
62
- const personStore = createStore();
63
- LinkedStorage.setDefaultStore(defaultStore.store);
64
- LinkedStorage.setStoreForShapes(personStore.store, RoutedPerson);
65
-
66
- await LinkedStorage.selectQuery({
67
- type: 'select',
68
- select: [],
69
- shape: RoutedPerson,
70
- } as any);
71
-
72
- expect(personStore.calls.select).toBe(1);
73
- expect(defaultStore.calls.select).toBe(0);
74
- });
75
-
76
- test('routes select queries to default store when no mapping exists', async () => {
77
- const defaultStore = createStore();
78
- LinkedStorage.setDefaultStore(defaultStore.store);
79
-
80
- await LinkedStorage.selectQuery({
81
- type: 'select',
82
- select: [],
83
- shape: RoutedPet,
84
- } as any);
85
-
86
- expect(defaultStore.calls.select).toBe(1);
87
- });
88
-
89
- test('uses parent shape store for subclasses', async () => {
90
- const defaultStore = createStore();
91
- const personStore = createStore();
92
- LinkedStorage.setDefaultStore(defaultStore.store);
93
- LinkedStorage.setStoreForShapes(personStore.store, RoutedPerson);
94
-
95
- await LinkedStorage.selectQuery({
96
- type: 'select',
97
- select: [],
98
- shape: RoutedEmployee,
99
- } as any);
100
-
101
- expect(personStore.calls.select).toBe(1);
102
- expect(defaultStore.calls.select).toBe(0);
103
- });
104
-
105
- test('routes update/create/delete using node shape ids', async () => {
106
- const defaultStore = createStore();
107
- const personStore = createStore();
108
- LinkedStorage.setDefaultStore(defaultStore.store);
109
- LinkedStorage.setStoreForShapes(personStore.store, RoutedPerson);
110
-
111
- await LinkedStorage.updateQuery({
112
- type: 'update',
113
- id: 'p1',
114
- shape: RoutedPerson.shape,
115
- updates: {},
116
- } as any);
117
- await LinkedStorage.createQuery({
118
- type: 'create',
119
- shape: RoutedPerson.shape,
120
- updates: {},
121
- } as any);
122
- await LinkedStorage.deleteQuery({
123
- type: 'delete',
124
- ids: [{id: 'p1'}],
125
- shape: RoutedPerson.shape,
126
- } as any);
127
-
128
- expect(personStore.calls.update).toBe(1);
129
- expect(personStore.calls.create).toBe(1);
130
- expect(personStore.calls.delete).toBe(1);
131
- expect(defaultStore.calls.update).toBe(0);
132
- });
133
- });
@@ -1,25 +0,0 @@
1
- export interface IErrorLogger {
2
- log?(error: any): Promise<void>;
3
- }
4
-
5
- /**
6
- * Utility class to log errors.
7
- * Install any error client package like lincd-sentry in your app to log errors.
8
- */
9
- export class LinkedErrorLogging {
10
- private static logger: IErrorLogger;
11
-
12
- static setDefaultLogger(logger: IErrorLogger) {
13
- this.logger = logger;
14
- }
15
-
16
- static hasDefaultLogger() {
17
- return this.logger && true;
18
- }
19
-
20
- static log(error: Error) {
21
- if (this.logger) {
22
- return this.logger.log(error);
23
- }
24
- }
25
- }
@@ -1,75 +0,0 @@
1
- import {IFileStore} from '../interfaces/IFileStore.js';
2
- import type {Readable} from 'stream';
3
-
4
- export abstract class LinkedFileStorage {
5
- private static defaultStore: IFileStore;
6
- private static url: string; // default accessURL
7
-
8
- static get accessURL(): string {
9
- // check if default store is not set, return default accessURL
10
- if (!this.defaultStore) {
11
- return this.url;
12
- }
13
-
14
- return this.defaultStore.accessURL;
15
- }
16
-
17
- static setDefaultAccessURL(accessURL: string): string {
18
- return (this.url = accessURL);
19
- }
20
-
21
- static getDefaultStore(): IFileStore {
22
- return this.defaultStore;
23
- }
24
-
25
- static setDefaultStore(store: IFileStore) {
26
- this.defaultStore = store;
27
-
28
- if (this.defaultStore.init) {
29
- this.defaultStore.init();
30
- }
31
- }
32
-
33
- static deleteFile(filePath: string): Promise<void> {
34
- return this.defaultStore.deleteFile(filePath);
35
- }
36
-
37
- static fileExists(filePath: string): Promise<boolean> {
38
- return this.defaultStore.fileExists(filePath);
39
- }
40
-
41
- static getFile(filePath: string): Promise<Buffer> {
42
- return this.defaultStore.getFile(filePath);
43
- }
44
-
45
- static listFiles(prefix?: string): Promise<string[]> {
46
- return this.defaultStore.listFiles(prefix);
47
- }
48
-
49
- static saveFile(
50
- filePath: string,
51
- fileContent: string | Uint8Array | Buffer | Readable,
52
- mimeType?: string,
53
- preventDuplicates: boolean = false,
54
- ): Promise<string> {
55
- return this.defaultStore.saveFile(
56
- filePath,
57
- fileContent,
58
- mimeType,
59
- preventDuplicates,
60
- );
61
- }
62
- }
63
-
64
- /**
65
- * Get the full path of an asset based on the way LinkedFileStorage is configured
66
- * Returns accessURL + directory (/public by default) + path
67
- * @param path asset path
68
- * @param directory asset directory (optional, default is /public)
69
- * @returns asset url. e.g. https://cdn.example.com/public/image.png
70
- */
71
- export function asset(path: string, directory: string = '/public'): string {
72
- const accessURL = LinkedFileStorage.accessURL;
73
- const assetUrl = accessURL + directory + path;
74
- return assetUrl;
75
- }
@@ -1,120 +0,0 @@
1
- import {CoreMap} from '../collections/CoreMap.js';
2
- import {CoreSet} from '../collections/CoreSet.js';
3
- import {IQuadStore} from '../interfaces/IQuadStore.js';
4
- import {CreateQuery} from '../queries/CreateQuery.js';
5
- import {DeleteQuery, DeleteResponse} from '../queries/DeleteQuery.js';
6
- import {SelectQuery} from '../queries/SelectQuery.js';
7
- import {UpdateQuery} from '../queries/UpdateQuery.js';
8
- import {Shape, ShapeType} from '../shapes/Shape.js';
9
- import {getShapeClass} from './ShapeClass.js';
10
-
11
- export abstract class LinkedStorage {
12
- private static defaultStore?: IQuadStore;
13
- private static shapeToStore: CoreMap<typeof Shape, IQuadStore> =
14
- new CoreMap();
15
-
16
- static isInitialised() {
17
- return !!this.defaultStore;
18
- }
19
-
20
- static getDefaultStore() {
21
- return this.defaultStore;
22
- }
23
-
24
- static setDefaultStore(store: IQuadStore) {
25
- this.defaultStore = store;
26
- if (this.defaultStore?.init) {
27
- this.defaultStore.init();
28
- }
29
- }
30
-
31
- static setStoreForShapes(store: IQuadStore, ...shapeClasses: (typeof Shape)[]) {
32
- shapeClasses.forEach((shapeClass) => {
33
- this.shapeToStore.set(shapeClass, store);
34
- });
35
- }
36
-
37
- static getStores(): CoreSet<IQuadStore> {
38
- const stores = new CoreSet<IQuadStore>();
39
- if (this.defaultStore) {
40
- stores.add(this.defaultStore);
41
- }
42
- this.shapeToStore.forEach((store) => stores.add(store));
43
- return stores;
44
- }
45
-
46
- static getShapeToStoreMap(): CoreMap<typeof Shape, IQuadStore> {
47
- return this.shapeToStore;
48
- }
49
-
50
- static getStoreForShapeClass(shapeClass?: typeof Shape | null): IQuadStore {
51
- let current = shapeClass || null;
52
- while (current) {
53
- const store = this.shapeToStore.get(current);
54
- if (store) {
55
- return store;
56
- }
57
- if (current === Shape) {
58
- break;
59
- }
60
- current = Object.getPrototypeOf(current);
61
- }
62
- return this.defaultStore;
63
- }
64
-
65
- private static resolveStoreForQueryShape(
66
- shape?: {id?: string} | typeof Shape | ShapeType | null,
67
- ): IQuadStore {
68
- if (!shape) {
69
- return this.defaultStore;
70
- }
71
- if (typeof shape === 'function') {
72
- return this.getStoreForShapeClass(shape as typeof Shape);
73
- }
74
- if (shape.id) {
75
- const shapeClass = getShapeClass(shape.id);
76
- return this.getStoreForShapeClass(shapeClass);
77
- }
78
- return this.defaultStore;
79
- }
80
-
81
- static selectQuery<ResultType>(query: SelectQuery<any>): Promise<ResultType> {
82
- const store = this.resolveStoreForQueryShape(query?.shape);
83
- if (!store?.selectQuery) {
84
- return Promise.reject(
85
- new Error('No query store configured. Call LinkedStorage.setDefaultStore().'),
86
- );
87
- }
88
- return store.selectQuery(query);
89
- }
90
-
91
- static updateQuery<ResponseType>(query: UpdateQuery<ResponseType>) {
92
- const store = this.resolveStoreForQueryShape(query?.shape);
93
- if (!store?.updateQuery) {
94
- return Promise.reject(
95
- new Error('No update handler configured on the query store.'),
96
- );
97
- }
98
- return store.updateQuery(query);
99
- }
100
-
101
- static createQuery<ResponseType>(query: CreateQuery<ResponseType>) {
102
- const store = this.resolveStoreForQueryShape(query?.shape);
103
- if (!store?.createQuery) {
104
- return Promise.reject(
105
- new Error('No create handler configured on the query store.'),
106
- );
107
- }
108
- return store.createQuery(query);
109
- }
110
-
111
- static deleteQuery(query: DeleteQuery): Promise<DeleteResponse> {
112
- const store = this.resolveStoreForQueryShape(query?.shape);
113
- if (!store?.deleteQuery) {
114
- return Promise.reject(
115
- new Error('No delete handler configured on the query store.'),
116
- );
117
- }
118
- return store.deleteQuery(query);
119
- }
120
- }
@@ -1,5 +0,0 @@
1
- import {NodeReferenceValue} from './NodeReference.js';
2
-
3
- export const createNameSpace = (nameSpace: string) => {
4
- return (term: string): NodeReferenceValue => ({id: nameSpace + term});
5
- };
@@ -1,16 +0,0 @@
1
- export type NodeReferenceValue = {id: string};
2
-
3
- export type NodeReferenceInput = NodeReferenceValue | string;
4
-
5
- export function toNodeReference(value: NodeReferenceInput): NodeReferenceValue {
6
- return typeof value === 'string' ? {id: value} : value;
7
- }
8
-
9
- export function isNodeReferenceValue(value: unknown): value is NodeReferenceValue {
10
- return (
11
- typeof value === 'object' &&
12
- value !== null &&
13
- 'id' in value &&
14
- typeof (value as NodeReferenceValue).id === 'string'
15
- );
16
- }