@_linked/rdf-mem-store 0.0.1

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 (137) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +285 -0
  3. package/lib/cjs/Datafactory.d.ts +29 -0
  4. package/lib/cjs/Datafactory.js +101 -0
  5. package/lib/cjs/Datafactory.js.map +1 -0
  6. package/lib/cjs/InMemoryStore.d.ts +35 -0
  7. package/lib/cjs/InMemoryStore.js +98 -0
  8. package/lib/cjs/InMemoryStore.js.map +1 -0
  9. package/lib/cjs/collections/NodeMap.d.ts +35 -0
  10. package/lib/cjs/collections/NodeMap.js +244 -0
  11. package/lib/cjs/collections/NodeMap.js.map +1 -0
  12. package/lib/cjs/collections/NodeSet.d.ts +55 -0
  13. package/lib/cjs/collections/NodeSet.js +296 -0
  14. package/lib/cjs/collections/NodeSet.js.map +1 -0
  15. package/lib/cjs/collections/NodeURIMappings.d.ts +20 -0
  16. package/lib/cjs/collections/NodeURIMappings.js +65 -0
  17. package/lib/cjs/collections/NodeURIMappings.js.map +1 -0
  18. package/lib/cjs/collections/NodeValuesSet.d.ts +63 -0
  19. package/lib/cjs/collections/NodeValuesSet.js +100 -0
  20. package/lib/cjs/collections/NodeValuesSet.js.map +1 -0
  21. package/lib/cjs/collections/QuadArray.d.ts +17 -0
  22. package/lib/cjs/collections/QuadArray.js +67 -0
  23. package/lib/cjs/collections/QuadArray.js.map +1 -0
  24. package/lib/cjs/collections/QuadMap.d.ts +64 -0
  25. package/lib/cjs/collections/QuadMap.js +155 -0
  26. package/lib/cjs/collections/QuadMap.js.map +1 -0
  27. package/lib/cjs/collections/QuadSet.d.ts +22 -0
  28. package/lib/cjs/collections/QuadSet.js +106 -0
  29. package/lib/cjs/collections/QuadSet.js.map +1 -0
  30. package/lib/cjs/collections/SearchMap.d.ts +5 -0
  31. package/lib/cjs/collections/SearchMap.js +13 -0
  32. package/lib/cjs/collections/SearchMap.js.map +1 -0
  33. package/lib/cjs/events/EventBatcher.d.ts +20 -0
  34. package/lib/cjs/events/EventBatcher.js +97 -0
  35. package/lib/cjs/events/EventBatcher.js.map +1 -0
  36. package/lib/cjs/events/EventEmitter.d.ts +15 -0
  37. package/lib/cjs/events/EventEmitter.js +102 -0
  38. package/lib/cjs/events/EventEmitter.js.map +1 -0
  39. package/lib/cjs/index.d.ts +14 -0
  40. package/lib/cjs/index.js +48 -0
  41. package/lib/cjs/index.js.map +1 -0
  42. package/lib/cjs/interfaces/IGraphObject.d.ts +29 -0
  43. package/lib/cjs/interfaces/IGraphObject.js +3 -0
  44. package/lib/cjs/interfaces/IGraphObject.js.map +1 -0
  45. package/lib/cjs/interfaces/IGraphObjectSet.d.ts +24 -0
  46. package/lib/cjs/interfaces/IGraphObjectSet.js +3 -0
  47. package/lib/cjs/interfaces/IGraphObjectSet.js.map +1 -0
  48. package/lib/cjs/interfaces/IShape.d.ts +22 -0
  49. package/lib/cjs/interfaces/IShape.js +3 -0
  50. package/lib/cjs/interfaces/IShape.js.map +1 -0
  51. package/lib/cjs/interfaces/ISingleGraphObject.d.ts +3 -0
  52. package/lib/cjs/interfaces/ISingleGraphObject.js +3 -0
  53. package/lib/cjs/interfaces/ISingleGraphObject.js.map +1 -0
  54. package/lib/cjs/models.d.ts +1167 -0
  55. package/lib/cjs/models.js +2668 -0
  56. package/lib/cjs/models.js.map +1 -0
  57. package/lib/cjs/package.json +3 -0
  58. package/lib/cjs/utils/Debug.d.ts +3 -0
  59. package/lib/cjs/utils/Debug.js +46 -0
  60. package/lib/cjs/utils/Debug.js.map +1 -0
  61. package/lib/cjs/utils/LocalQueryResolver.d.ts +21 -0
  62. package/lib/cjs/utils/LocalQueryResolver.js +1442 -0
  63. package/lib/cjs/utils/LocalQueryResolver.js.map +1 -0
  64. package/lib/cjs/utils/URI.d.ts +18 -0
  65. package/lib/cjs/utils/URI.js +42 -0
  66. package/lib/cjs/utils/URI.js.map +1 -0
  67. package/lib/cjs/utils/toNamedNode.d.ts +8 -0
  68. package/lib/cjs/utils/toNamedNode.js +15 -0
  69. package/lib/cjs/utils/toNamedNode.js.map +1 -0
  70. package/lib/esm/Datafactory.d.ts +29 -0
  71. package/lib/esm/Datafactory.js +97 -0
  72. package/lib/esm/Datafactory.js.map +1 -0
  73. package/lib/esm/InMemoryStore.d.ts +35 -0
  74. package/lib/esm/InMemoryStore.js +94 -0
  75. package/lib/esm/InMemoryStore.js.map +1 -0
  76. package/lib/esm/collections/NodeMap.d.ts +35 -0
  77. package/lib/esm/collections/NodeMap.js +240 -0
  78. package/lib/esm/collections/NodeMap.js.map +1 -0
  79. package/lib/esm/collections/NodeSet.d.ts +55 -0
  80. package/lib/esm/collections/NodeSet.js +292 -0
  81. package/lib/esm/collections/NodeSet.js.map +1 -0
  82. package/lib/esm/collections/NodeURIMappings.d.ts +20 -0
  83. package/lib/esm/collections/NodeURIMappings.js +61 -0
  84. package/lib/esm/collections/NodeURIMappings.js.map +1 -0
  85. package/lib/esm/collections/NodeValuesSet.d.ts +63 -0
  86. package/lib/esm/collections/NodeValuesSet.js +96 -0
  87. package/lib/esm/collections/NodeValuesSet.js.map +1 -0
  88. package/lib/esm/collections/QuadArray.d.ts +17 -0
  89. package/lib/esm/collections/QuadArray.js +63 -0
  90. package/lib/esm/collections/QuadArray.js.map +1 -0
  91. package/lib/esm/collections/QuadMap.d.ts +64 -0
  92. package/lib/esm/collections/QuadMap.js +151 -0
  93. package/lib/esm/collections/QuadMap.js.map +1 -0
  94. package/lib/esm/collections/QuadSet.d.ts +22 -0
  95. package/lib/esm/collections/QuadSet.js +102 -0
  96. package/lib/esm/collections/QuadSet.js.map +1 -0
  97. package/lib/esm/collections/SearchMap.d.ts +5 -0
  98. package/lib/esm/collections/SearchMap.js +9 -0
  99. package/lib/esm/collections/SearchMap.js.map +1 -0
  100. package/lib/esm/events/EventBatcher.d.ts +20 -0
  101. package/lib/esm/events/EventBatcher.js +90 -0
  102. package/lib/esm/events/EventBatcher.js.map +1 -0
  103. package/lib/esm/events/EventEmitter.d.ts +15 -0
  104. package/lib/esm/events/EventEmitter.js +98 -0
  105. package/lib/esm/events/EventEmitter.js.map +1 -0
  106. package/lib/esm/index.d.ts +14 -0
  107. package/lib/esm/index.js +22 -0
  108. package/lib/esm/index.js.map +1 -0
  109. package/lib/esm/interfaces/IGraphObject.d.ts +29 -0
  110. package/lib/esm/interfaces/IGraphObject.js +2 -0
  111. package/lib/esm/interfaces/IGraphObject.js.map +1 -0
  112. package/lib/esm/interfaces/IGraphObjectSet.d.ts +24 -0
  113. package/lib/esm/interfaces/IGraphObjectSet.js +2 -0
  114. package/lib/esm/interfaces/IGraphObjectSet.js.map +1 -0
  115. package/lib/esm/interfaces/IShape.d.ts +22 -0
  116. package/lib/esm/interfaces/IShape.js +2 -0
  117. package/lib/esm/interfaces/IShape.js.map +1 -0
  118. package/lib/esm/interfaces/ISingleGraphObject.d.ts +3 -0
  119. package/lib/esm/interfaces/ISingleGraphObject.js +2 -0
  120. package/lib/esm/interfaces/ISingleGraphObject.js.map +1 -0
  121. package/lib/esm/models.d.ts +1167 -0
  122. package/lib/esm/models.js +2659 -0
  123. package/lib/esm/models.js.map +1 -0
  124. package/lib/esm/package.json +3 -0
  125. package/lib/esm/utils/Debug.d.ts +3 -0
  126. package/lib/esm/utils/Debug.js +42 -0
  127. package/lib/esm/utils/Debug.js.map +1 -0
  128. package/lib/esm/utils/LocalQueryResolver.d.ts +21 -0
  129. package/lib/esm/utils/LocalQueryResolver.js +1434 -0
  130. package/lib/esm/utils/LocalQueryResolver.js.map +1 -0
  131. package/lib/esm/utils/URI.d.ts +18 -0
  132. package/lib/esm/utils/URI.js +38 -0
  133. package/lib/esm/utils/URI.js.map +1 -0
  134. package/lib/esm/utils/toNamedNode.d.ts +8 -0
  135. package/lib/esm/utils/toNamedNode.js +12 -0
  136. package/lib/esm/utils/toNamedNode.js.map +1 -0
  137. package/package.json +57 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @_linked/rdf-mem-store
2
+
3
+ ## 0.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Initial publish to reserve package name and set up CI/CD.
package/README.md ADDED
@@ -0,0 +1,285 @@
1
+ # @_linked/rdf-mem-store
2
+
3
+ In-memory RDF store for `@_linked/core`. Provides RDF model classes, an in-memory quad graph, and a query resolver that executes query objects generated by core's Shape-based query DSL.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @_linked/rdf-mem-store @_linked/core
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```typescript
14
+ import {LinkedStorage} from '@_linked/core';
15
+ import {InMemoryStore, NamedNode, Literal} from '@_linked/rdf-mem-store';
16
+
17
+ // 1. Create and wire the store
18
+ const store = new InMemoryStore();
19
+ LinkedStorage.setDefaultStore(store);
20
+
21
+ // 2. Create nodes and data
22
+ const alice = NamedNode.getOrCreate('https://example.org/alice');
23
+ const name = NamedNode.getOrCreate('https://schema.org/name');
24
+ alice.setValue(name, 'Alice');
25
+
26
+ // 3. Query using core's Shape DSL (see @_linked/core for Shape setup)
27
+ const results = await Person.select((p) => p.name);
28
+ ```
29
+
30
+ ## Wiring the store into core
31
+
32
+ `InMemoryStore` implements `IQuadStore` from `@_linked/core`. Register it as the default store so core's query DSL can resolve queries:
33
+
34
+ ```typescript
35
+ import {LinkedStorage} from '@_linked/core';
36
+ import {InMemoryStore} from '@_linked/rdf-mem-store';
37
+
38
+ const store = new InMemoryStore();
39
+ LinkedStorage.setDefaultStore(store);
40
+ ```
41
+
42
+ You can also route specific shapes to specific stores:
43
+
44
+ ```typescript
45
+ import {LinkedStorage} from '@_linked/core';
46
+ import {InMemoryStore} from '@_linked/rdf-mem-store';
47
+
48
+ const mainStore = new InMemoryStore();
49
+ const personStore = new InMemoryStore();
50
+
51
+ LinkedStorage.setDefaultStore(mainStore);
52
+ LinkedStorage.setStoreForShapes(personStore, Person);
53
+ ```
54
+
55
+ ## RDF models
56
+
57
+ This package provides the core RDF model classes. All nodes and quads are **global singletons** — calling `NamedNode.getOrCreate(uri)` twice with the same URI returns the same instance.
58
+
59
+ ### NamedNode
60
+
61
+ Represents a URI-identified RDF node. This is the primary building block.
62
+
63
+ ```typescript
64
+ import {NamedNode} from '@_linked/rdf-mem-store';
65
+
66
+ // Get or create a node (singleton per URI)
67
+ const node = NamedNode.getOrCreate('https://example.org/alice');
68
+
69
+ // Create a temporary node (auto-generated URI)
70
+ const temp = NamedNode.create();
71
+
72
+ // Check if a node exists without creating it
73
+ const existing = NamedNode.getNamedNode('https://example.org/alice'); // NamedNode | undefined
74
+ ```
75
+
76
+ `NamedNode` satisfies `NodeReferenceValue` (`{id: string}`) from core, so it can be used anywhere core expects a node reference.
77
+
78
+ ### Literal
79
+
80
+ Represents an RDF literal value (string, number, date, etc.).
81
+
82
+ ```typescript
83
+ import {Literal, NamedNode} from '@_linked/rdf-mem-store';
84
+
85
+ // Plain string literal
86
+ const lit = new Literal('hello');
87
+
88
+ // Typed literal (with datatype)
89
+ import {xsd} from '@_linked/core/ontologies/xsd';
90
+ import {toNamedNode} from '@_linked/rdf-mem-store';
91
+
92
+ const intLit = new Literal('42', toNamedNode(xsd.integer));
93
+ const dateLit = new Literal('2024-01-01T00:00:00.000Z', toNamedNode(xsd.dateTime));
94
+ const boolLit = new Literal('true', toNamedNode(xsd.boolean));
95
+ ```
96
+
97
+ ### Quad
98
+
99
+ Represents an RDF triple/quad (subject-predicate-object-graph).
100
+
101
+ ```typescript
102
+ import {Quad, NamedNode, Literal, defaultGraph} from '@_linked/rdf-mem-store';
103
+
104
+ const subject = NamedNode.getOrCreate('https://example.org/alice');
105
+ const predicate = NamedNode.getOrCreate('https://schema.org/name');
106
+ const object = new Literal('Alice');
107
+
108
+ // Quads are also singletons
109
+ const quad = Quad.getOrCreate(subject, predicate, object, defaultGraph);
110
+ ```
111
+
112
+ ### Graph
113
+
114
+ Represents an RDF named graph.
115
+
116
+ ```typescript
117
+ import {Graph, defaultGraph} from '@_linked/rdf-mem-store';
118
+
119
+ const myGraph = Graph.getOrCreate('https://example.org/my-graph');
120
+ // defaultGraph is the default graph singleton
121
+ ```
122
+
123
+ ## Working with properties
124
+
125
+ `NamedNode` provides methods for setting, getting, and removing property values.
126
+
127
+ ### Setting properties
128
+
129
+ ```typescript
130
+ const alice = NamedNode.getOrCreate('https://example.org/alice');
131
+ const name = NamedNode.getOrCreate('https://schema.org/name');
132
+ const knows = NamedNode.getOrCreate('https://schema.org/knows');
133
+ const bob = NamedNode.getOrCreate('https://example.org/bob');
134
+
135
+ // Set a literal value (creates a Literal and a Quad)
136
+ alice.setValue(name, 'Alice');
137
+
138
+ // Set an object property (node-to-node link)
139
+ alice.set(knows, bob);
140
+
141
+ // Set multiple values at once
142
+ const carol = NamedNode.getOrCreate('https://example.org/carol');
143
+ alice.mset(knows, [bob, carol]);
144
+
145
+ // Overwrite a property (removes existing values first)
146
+ alice.overwrite(name, new Literal('Alicia'));
147
+
148
+ // Overwrite with multiple values
149
+ alice.moverwrite(knows, [bob, carol]);
150
+ ```
151
+
152
+ ### Getting properties
153
+
154
+ ```typescript
155
+ // Get a single value
156
+ const oneKnown = alice.getOne(knows); // Node | undefined
157
+
158
+ // Get all values for a property
159
+ const allKnown = alice.getAll(knows); // NodeValuesSet (iterable)
160
+
161
+ // Get a string value directly
162
+ const nameStr = alice.getValue(name); // string
163
+
164
+ // Get all nodes that point to this node via a property
165
+ const whoKnowsAlice = alice.getAllInverse(knows); // NodeSet<NamedNode>
166
+
167
+ // Check if a property exists
168
+ const hasName = alice.hasProperty(name); // boolean
169
+
170
+ // Get quads for a property
171
+ const quads = alice.getQuads(knows); // QuadSet
172
+ ```
173
+
174
+ ### Removing properties
175
+
176
+ ```typescript
177
+ // Remove a specific value
178
+ alice.unset(knows, bob);
179
+
180
+ // Remove all values for a property
181
+ alice.unsetAll(knows);
182
+
183
+ // Remove the node entirely (removes all quads where it is subject or object)
184
+ alice.remove();
185
+ ```
186
+
187
+ ## Setting up typed data (with Shapes)
188
+
189
+ When using core's Shape DSL, you define shapes and set up data using the RDF model layer. The query resolver traverses the global quad graph to resolve queries.
190
+
191
+ ```typescript
192
+ import {NamedNode, Literal, toNamedNode} from '@_linked/rdf-mem-store';
193
+ import {rdf} from '@_linked/core/ontologies/rdf';
194
+ import {InMemoryStore} from '@_linked/rdf-mem-store';
195
+ import {LinkedStorage} from '@_linked/core';
196
+
197
+ // Assume you have a Person shape with targetClass and properties defined via core
198
+ // (see @_linked/core README for Shape setup)
199
+
200
+ // Create typed entities
201
+ const personType = toNamedNode(Person.targetClass);
202
+ const rdfType = toNamedNode(rdf.type);
203
+ const nameProp = toNamedNode(name); // name from your shape's property path
204
+
205
+ const alice = NamedNode.getOrCreate('https://example.org/alice');
206
+ alice.set(rdfType, personType); // Set rdf:type so the resolver finds this instance
207
+ alice.setValue(nameProp, 'Alice'); // Set the name property
208
+
209
+ // Wire the store
210
+ const store = new InMemoryStore();
211
+ LinkedStorage.setDefaultStore(store);
212
+
213
+ // Now queries work
214
+ const results = await Person.select((p) => p.name);
215
+ // → [{id: 'https://example.org/alice', name: 'Alice'}]
216
+ ```
217
+
218
+ ## toNamedNode helper
219
+
220
+ Since core uses `NodeReferenceValue` (`{id: string}`) for ontology terms, property paths, and target classes, use `toNamedNode` to convert them to `NamedNode` instances when working with the RDF model layer:
221
+
222
+ ```typescript
223
+ import {toNamedNode} from '@_linked/rdf-mem-store';
224
+ import {rdf} from '@_linked/core/ontologies/rdf';
225
+
226
+ // rdf.type is {id: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'}
227
+ const rdfTypeNode = toNamedNode(rdf.type); // → NamedNode
228
+
229
+ // Works with any {id: string} object
230
+ const node = toNamedNode({id: 'https://example.org/foo'}); // → NamedNode
231
+
232
+ // Passes through NamedNode instances unchanged
233
+ const nn = NamedNode.getOrCreate('https://example.org/bar');
234
+ toNamedNode(nn) === nn; // true
235
+ ```
236
+
237
+ ## InMemoryStore API
238
+
239
+ `InMemoryStore` implements `IQuadStore` from core (query methods) and provides additional quad-level methods:
240
+
241
+ ```typescript
242
+ const store = new InMemoryStore();
243
+
244
+ // Query methods (from IQuadStore)
245
+ await store.selectQuery(query); // Resolve a select query
246
+ await store.updateQuery(query); // Resolve an update query
247
+ await store.createQuery(query); // Resolve a create query
248
+ await store.deleteQuery(query); // Resolve a delete query
249
+
250
+ // Quad-level methods
251
+ await store.add(quad); // Add a single quad
252
+ await store.addMultiple(quadSet); // Add multiple quads
253
+ await store.delete(quad); // Remove a single quad
254
+ await store.deleteMultiple(quadSet); // Remove multiple quads
255
+
256
+ // Inspect contents
257
+ store.getContents(); // Returns the QuadSet of tracked quads
258
+ ```
259
+
260
+ ## RDF collections
261
+
262
+ - **`QuadSet`** — Set of Quad instances
263
+ - **`QuadArray`** — Array of Quad instances
264
+ - **`QuadMap`** — Map indexed by quads
265
+ - **`NodeSet`** — Set of NamedNode instances
266
+ - **`NodeMap`** — Map keyed by NamedNode
267
+ - **`NodeURIMappings`** — URI-to-node mapping utilities
268
+ - **`SearchMap`** — Search-optimized map for quad lookups
269
+ - **`NodeValuesSet`** — Set of values for a specific property on a node (returned by `node.getAll()`)
270
+
271
+ ## Related packages
272
+
273
+ - `@_linked/core` — Query DSL, Shape classes, SHACL decorators, LinkedStorage
274
+ - `@_linked/react` — React bindings for Linked queries and shapes
275
+
276
+ ## Changelog
277
+
278
+ ### 1.0.0 (from LINCD.js)
279
+
280
+ Initial extraction from the LINCD monolith. Moves all RDF model classes, the in-memory quad store, and the query resolver into a standalone package.
281
+
282
+ - RDF models (`NamedNode`, `Literal`, `BlankNode`, `Quad`, `Graph`) and all RDF collections extracted from `lincd`.
283
+ - `InMemoryStore` implements `IQuadStore` from `@_linked/core`.
284
+ - `LocalQueryResolver` resolves core's query objects against the in-memory quad graph.
285
+ - `toNamedNode` helper bridges core's `NodeReferenceValue` (`{id: string}`) to `NamedNode` instances.
@@ -0,0 +1,29 @@
1
+ import { Graph, Literal, NamedNode } from './models.js';
2
+ import { Term } from 'rdflib/lib/tf-types';
3
+ import { NodeURIMappings } from './collections/NodeURIMappings.js';
4
+ import { QuadSet } from './collections/QuadSet.js';
5
+ interface DataFactoryConfig {
6
+ preventNewQuads?: boolean;
7
+ emitEvents?: boolean;
8
+ triggerStorage?: boolean;
9
+ nodeMap?: NodeURIMappings;
10
+ targetGraph?: Graph;
11
+ overwriteData?: boolean;
12
+ }
13
+ export declare class Datafactory {
14
+ quads: QuadSet;
15
+ private nodeMap?;
16
+ private preventNewQuads;
17
+ private emitEvents;
18
+ private triggerStorage;
19
+ private targetGraph;
20
+ private clearedProps;
21
+ private overwriteData?;
22
+ constructor(config?: DataFactoryConfig);
23
+ namedNode(uri: string): NamedNode;
24
+ literal(value: any, languageOrDatatype: any): Literal;
25
+ blankNode(value: any): import("./models.js").BlankNode;
26
+ defaultGraph(): any;
27
+ quad(subject: Term, predicate: Term, object: Term, graph: Term): any;
28
+ }
29
+ export {};
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Datafactory = void 0;
4
+ const models_js_1 = require("./models.js");
5
+ const NodeURIMappings_js_1 = require("./collections/NodeURIMappings.js");
6
+ const QuadSet_js_1 = require("./collections/QuadSet.js");
7
+ const CoreMap_1 = require("@_linked/core/collections/CoreMap");
8
+ const CoreSet_1 = require("@_linked/core/collections/CoreSet");
9
+ class Datafactory {
10
+ constructor(config) {
11
+ this.quads = new QuadSet_js_1.QuadSet();
12
+ this.emitEvents = true;
13
+ this.triggerStorage = false;
14
+ for (let key in config) {
15
+ this[key] = config[key];
16
+ }
17
+ if (!(config === null || config === void 0 ? void 0 : config.nodeMap)) {
18
+ this.nodeMap = new NodeURIMappings_js_1.NodeURIMappings();
19
+ }
20
+ this.quad = this.quad.bind(this);
21
+ this.blankNode = this.blankNode.bind(this);
22
+ this.namedNode = this.namedNode.bind(this);
23
+ this.literal = this.literal.bind(this);
24
+ if (config === null || config === void 0 ? void 0 : config.overwriteData) {
25
+ this.clearedProps = new CoreMap_1.CoreMap();
26
+ }
27
+ }
28
+ //TODO:
29
+ // Variable variable(DOMString value);
30
+ // Term fromTerm(Term original);
31
+ // Quad fromQuad(Quad original);
32
+ namedNode(uri) {
33
+ return models_js_1.NamedNode.getOrCreate(uri);
34
+ }
35
+ literal(value, languageOrDatatype) {
36
+ if (languageOrDatatype instanceof models_js_1.NamedNode) {
37
+ return new models_js_1.Literal(value, languageOrDatatype);
38
+ }
39
+ else {
40
+ return new models_js_1.Literal(value, null, languageOrDatatype);
41
+ }
42
+ }
43
+ blankNode(value) {
44
+ //when using start/end blanknode space you can let the factory reuse the same blank nodes
45
+ // if (this.nodeMap) {
46
+ return this.nodeMap.getOrCreateBlankNode(value);
47
+ // }
48
+ // return BlankNode.getOrCreate(value);
49
+ }
50
+ defaultGraph() {
51
+ return models_js_1.defaultGraph;
52
+ }
53
+ quad(subject, predicate, object, graph) {
54
+ //if a target graph is given, we always use that, regardless of whether there was any graph present in the data
55
+ //else if a graph was in the data, use that, or fall back to default graph
56
+ if (this.targetGraph) {
57
+ graph = this.targetGraph;
58
+ }
59
+ else if (!graph) {
60
+ graph = models_js_1.defaultGraph;
61
+ }
62
+ //in LINCD we use Graph objects which extend NamedNode
63
+ //but when parsing with N3 we get NamedNode objects
64
+ if (graph instanceof models_js_1.NamedNode) {
65
+ graph = models_js_1.Graph.getOrCreate(graph.uri);
66
+ }
67
+ //sometimes we want to update the graph with new data coming in from JSONLD
68
+ //so if overwrite data is true, we clear old data for any subj/pred combination we find
69
+ if (this.overwriteData &&
70
+ (!this.clearedProps.has(subject) ||
71
+ !this.clearedProps
72
+ .get(subject)
73
+ .has(predicate))) {
74
+ //remove without triggering storage events
75
+ subject.getQuads(predicate).removeAll(false);
76
+ if (!this.clearedProps.has(subject)) {
77
+ this.clearedProps.set(subject, new CoreSet_1.CoreSet());
78
+ }
79
+ this.clearedProps.get(subject).add(predicate);
80
+ }
81
+ let quad;
82
+ if (this.preventNewQuads) {
83
+ quad = models_js_1.Quad.get(subject, predicate, object, graph);
84
+ if (quad) {
85
+ this.quads.add(quad);
86
+ }
87
+ else {
88
+ //NOTE: this is not standard, so preventNewQuads will not work with other tools
89
+ //But it is useful for LINCD, where we want to prevent new quads from being created. Like when we share quads to be removed with other threads
90
+ return true;
91
+ }
92
+ }
93
+ else {
94
+ quad = models_js_1.Quad.getOrCreate(subject, predicate, object, graph, false, this.triggerStorage, this.emitEvents);
95
+ this.quads.add(quad);
96
+ }
97
+ return quad;
98
+ }
99
+ }
100
+ exports.Datafactory = Datafactory;
101
+ //# sourceMappingURL=Datafactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Datafactory.js","sourceRoot":"","sources":["../../src/Datafactory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { IQuadStore } from '@_linked/core/interfaces/IQuadStore';
2
+ import { SelectQuery } from '@_linked/core/queries/SelectQuery';
3
+ import { UpdateQuery } from '@_linked/core/queries/UpdateQuery';
4
+ import { CreateQuery } from '@_linked/core/queries/CreateQuery';
5
+ import { DeleteQuery, DeleteResponse } from '@_linked/core/queries/DeleteQuery';
6
+ import { Graph, Quad } from './models';
7
+ import { QuadSet } from './collections/QuadSet';
8
+ import { QuadArray } from './collections/QuadArray';
9
+ export declare class InMemoryStore implements IQuadStore {
10
+ /**
11
+ * You can use this to define (overwrite) which graph this store uses for its quads
12
+ */
13
+ targetGraph: Graph;
14
+ protected contents: QuadSet;
15
+ private initPromise;
16
+ init(): Promise<any>;
17
+ loadContents(): Promise<QuadSet>;
18
+ /**
19
+ * returns the contents of the InMemoryStore as a QuadSet
20
+ * do NOT modify the returned QuadSet directly. Add or remove contents to this store instead
21
+ */
22
+ getContents(): QuadSet;
23
+ selectQuery<ResultType>(query: SelectQuery<any>): Promise<ResultType>;
24
+ updateQuery?<RType>(query: UpdateQuery<RType>): Promise<RType>;
25
+ createQuery?<R>(q: CreateQuery<R>): Promise<R>;
26
+ deleteQuery(query: DeleteQuery): Promise<DeleteResponse>;
27
+ add(quad: Quad): Promise<any>;
28
+ addMultiple(quads: QuadSet): Promise<any>;
29
+ delete(quad: Quad): Promise<any>;
30
+ deleteMultiple(quads: QuadSet): Promise<any>;
31
+ protected onContentsUpdated(): Promise<boolean>;
32
+ protected addNewContents(quads: QuadArray | QuadSet): QuadArray | QuadSet;
33
+ private _addMultiple;
34
+ private _deleteMultiple;
35
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryStore = void 0;
4
+ const LocalQueryResolver_1 = require("./utils/LocalQueryResolver");
5
+ const models_1 = require("./models");
6
+ const QuadSet_1 = require("./collections/QuadSet");
7
+ const QuadArray_1 = require("./collections/QuadArray");
8
+ class InMemoryStore {
9
+ init() {
10
+ if (!this.initPromise) {
11
+ this.initPromise = this.loadContents();
12
+ }
13
+ return this.initPromise;
14
+ }
15
+ loadContents() {
16
+ //by default an in-memory store starts empty - it has no permanent storage
17
+ //overwrite this method to change that
18
+ this.contents = new QuadSet_1.QuadSet();
19
+ return Promise.resolve(this.contents);
20
+ }
21
+ /**
22
+ * returns the contents of the InMemoryStore as a QuadSet
23
+ * do NOT modify the returned QuadSet directly. Add or remove contents to this store instead
24
+ */
25
+ getContents() {
26
+ return this.contents;
27
+ }
28
+ selectQuery(query) {
29
+ return Promise.resolve((0, LocalQueryResolver_1.resolveLocal)(query)).catch((e) => {
30
+ console.error('Error in query', e);
31
+ return new QuadArray_1.QuadArray();
32
+ });
33
+ }
34
+ updateQuery(query) {
35
+ return Promise.resolve((0, LocalQueryResolver_1.updateLocal)(query));
36
+ }
37
+ createQuery(q) {
38
+ return Promise.resolve((0, LocalQueryResolver_1.createLocal)(q));
39
+ }
40
+ deleteQuery(query) {
41
+ return Promise.resolve((0, LocalQueryResolver_1.deleteLocal)(query));
42
+ }
43
+ add(quad) {
44
+ return this.init().then(() => {
45
+ this.addNewContents(new QuadArray_1.QuadArray(quad));
46
+ this.onContentsUpdated();
47
+ return Promise.resolve(true);
48
+ });
49
+ }
50
+ addMultiple(quads) {
51
+ return this.init().then(() => {
52
+ this._addMultiple(quads);
53
+ this.onContentsUpdated();
54
+ return Promise.resolve(true);
55
+ });
56
+ }
57
+ delete(quad) {
58
+ return this.init().then(() => {
59
+ this._deleteMultiple(new QuadArray_1.QuadArray(quad));
60
+ this.onContentsUpdated();
61
+ return true;
62
+ });
63
+ }
64
+ deleteMultiple(quads) {
65
+ return this.init().then(() => {
66
+ this._deleteMultiple(quads);
67
+ this.onContentsUpdated();
68
+ return true;
69
+ });
70
+ }
71
+ onContentsUpdated() {
72
+ //by default in memory store does nothing here. Extending classes could choose to sync to a more permanent form of storage
73
+ return Promise.resolve(false);
74
+ }
75
+ addNewContents(quads) {
76
+ let graph = this.targetGraph || models_1.defaultGraph;
77
+ if (graph) {
78
+ quads = quads.moveTo(graph, false);
79
+ }
80
+ this.contents.addFrom(quads);
81
+ return quads;
82
+ }
83
+ _addMultiple(quads) {
84
+ this.addNewContents(quads);
85
+ }
86
+ _deleteMultiple(quads) {
87
+ let graph = this.targetGraph || models_1.defaultGraph;
88
+ if (graph) {
89
+ quads = quads.moveTo(graph, false);
90
+ }
91
+ quads.forEach((quad) => {
92
+ this.contents.delete(quad);
93
+ quad.remove(false);
94
+ });
95
+ }
96
+ }
97
+ exports.InMemoryStore = InMemoryStore;
98
+ //# sourceMappingURL=InMemoryStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryStore.js","sourceRoot":"","sources":["../../src/InMemoryStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { CoreMap } from '@_linked/core/collections/CoreMap';
2
+ import { IGraphObjectSet } from '../interfaces/IGraphObjectSet.js';
3
+ import { NamedNode, Node } from '../models.js';
4
+ import { QuadSet } from './QuadSet.js';
5
+ import { QuadArray } from './QuadArray.js';
6
+ import { NodeSet } from './NodeSet.js';
7
+ import { ICoreIterable } from '@_linked/core/interfaces/ICoreIterable';
8
+ export declare class NodeMap<R extends Node> extends CoreMap<string, R> implements IGraphObjectSet<R> {
9
+ constructor(iterable?: Iterable<[string, R]>);
10
+ getQuads(property: NamedNode): QuadSet;
11
+ getInverseQuads(property: NamedNode): QuadSet;
12
+ getAll(property: NamedNode): NodeSet;
13
+ getAllInverse(property: NamedNode): NodeSet<NamedNode>;
14
+ getMultipleInverse(properties: ICoreIterable<NamedNode>): NodeSet;
15
+ getMultiple(properties: ICoreIterable<NamedNode>): NodeSet;
16
+ getDeep(property: NamedNode, maxDepth?: number): NodeSet;
17
+ getOneFromPath(...properties: NamedNode[]): Node | undefined;
18
+ getAllFromPath(...properties: NamedNode[]): NodeSet;
19
+ getProperties(includeFromIncomingArcs?: boolean): NodeSet<NamedNode>;
20
+ getInverseProperties(): NodeSet<NamedNode>;
21
+ getOne(property: NamedNode): Node | any;
22
+ getOneInverse(property: NamedNode): NamedNode | any;
23
+ getAllQuads(includeAsObject?: boolean, includeImplicit?: boolean): QuadArray;
24
+ getAllInverseQuads(includeImplicit?: boolean): QuadArray;
25
+ where(property: NamedNode, value: Node): this;
26
+ getWhere(property: NamedNode, value: Node): Node | undefined;
27
+ setEach(property: NamedNode, value: Node): boolean;
28
+ msetEach(property: NamedNode, values: ICoreIterable<Node>): boolean;
29
+ updateEach(property: NamedNode, value: Node): boolean;
30
+ mupdateEach(property: NamedNode, values: ICoreIterable<Node>): boolean;
31
+ unsetEach(property: NamedNode, value: Node): boolean;
32
+ unsetAllEach(property: NamedNode): boolean;
33
+ promiseLoaded(loadInverseProperties?: boolean): Promise<boolean>;
34
+ isLoaded(includingInverseProperties?: boolean): boolean;
35
+ }