@undefineds.co/xpod 0.3.5 → 0.3.14

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 (253) hide show
  1. package/config/cli.json +1 -1
  2. package/config/cloud.json +54 -22
  3. package/config/local.json +56 -12
  4. package/config/resolver.json +10 -2
  5. package/config/xpod.base.json +50 -0
  6. package/config/xpod.json +8 -8
  7. package/dist/agents/config/resolve.js +10 -10
  8. package/dist/agents/config/resolve.js.map +1 -1
  9. package/dist/api/chatkit/index.d.ts +1 -1
  10. package/dist/api/chatkit/index.js.map +1 -1
  11. package/dist/api/chatkit/pod-store.d.ts +14 -11
  12. package/dist/api/chatkit/pod-store.js +114 -78
  13. package/dist/api/chatkit/pod-store.js.map +1 -1
  14. package/dist/api/chatkit/runtime/AcpAgentRuntime.js +1 -1
  15. package/dist/api/chatkit/runtime/AcpAgentRuntime.js.map +1 -1
  16. package/dist/api/chatkit/service.js +1 -1
  17. package/dist/api/chatkit/service.js.map +1 -1
  18. package/dist/api/chatkit/types.d.ts +11 -11
  19. package/dist/api/chatkit/types.js +3 -3
  20. package/dist/api/chatkit/types.js.map +1 -1
  21. package/dist/api/container/cloud.js +0 -8
  22. package/dist/api/container/cloud.js.map +1 -1
  23. package/dist/api/container/index.js +2 -1
  24. package/dist/api/container/index.js.map +1 -1
  25. package/dist/api/container/local.js +0 -7
  26. package/dist/api/container/local.js.map +1 -1
  27. package/dist/api/container/routes.js +3 -17
  28. package/dist/api/container/routes.js.map +1 -1
  29. package/dist/api/container/types.d.ts +0 -2
  30. package/dist/api/container/types.js.map +1 -1
  31. package/dist/api/handlers/PodManagementHandler.d.ts +3 -0
  32. package/dist/api/handlers/PodManagementHandler.js +71 -1
  33. package/dist/api/handlers/PodManagementHandler.js.map +1 -1
  34. package/dist/api/handlers/RunHandler.js +5 -5
  35. package/dist/api/handlers/RunHandler.js.map +1 -1
  36. package/dist/api/runs/AgentRuntimeTypes.d.ts +7 -8
  37. package/dist/api/runs/AgentRuntimeTypes.js.map +1 -1
  38. package/dist/api/runs/InngestRunExecutionBackend.d.ts +2 -2
  39. package/dist/api/runs/ManagedRunWorker.d.ts +1 -1
  40. package/dist/api/runs/ManagedRunWorker.js +6 -6
  41. package/dist/api/runs/ManagedRunWorker.js.map +1 -1
  42. package/dist/api/runs/PiAgentRuntimeDriver.d.ts +16 -1
  43. package/dist/api/runs/PiAgentRuntimeDriver.js +182 -23
  44. package/dist/api/runs/PiAgentRuntimeDriver.js.map +1 -1
  45. package/dist/api/runs/RunStateCenter.d.ts +3 -3
  46. package/dist/api/runs/RunStateCenter.js +13 -13
  47. package/dist/api/runs/RunStateCenter.js.map +1 -1
  48. package/dist/api/runs/store.d.ts +4 -4
  49. package/dist/api/runs/store.js +2 -2
  50. package/dist/api/runs/store.js.map +1 -1
  51. package/dist/api/service/VectorStoreService.d.ts +1 -1
  52. package/dist/api/service/VectorStoreService.js +16 -16
  53. package/dist/api/service/VectorStoreService.js.map +1 -1
  54. package/dist/api/tasks/InngestTaskScheduler.d.ts +4 -4
  55. package/dist/api/tasks/TaskMaterializer.d.ts +3 -3
  56. package/dist/api/tasks/TaskMaterializer.js +11 -11
  57. package/dist/api/tasks/TaskMaterializer.js.map +1 -1
  58. package/dist/api/tasks/TaskService.d.ts +3 -3
  59. package/dist/api/tasks/TaskService.js +11 -7
  60. package/dist/api/tasks/TaskService.js.map +1 -1
  61. package/dist/api/tasks/store.d.ts +10 -4
  62. package/dist/api/tasks/store.js +14 -4
  63. package/dist/api/tasks/store.js.map +1 -1
  64. package/dist/api/workspace/types.d.ts +3 -3
  65. package/dist/api/workspace/types.js +6 -6
  66. package/dist/api/workspace/types.js.map +1 -1
  67. package/dist/cli/commands/config.js +2 -2
  68. package/dist/cli/commands/config.js.map +1 -1
  69. package/dist/cli/commands/start.js +9 -3
  70. package/dist/cli/commands/start.js.map +1 -1
  71. package/dist/components/components.jsonld +8 -2
  72. package/dist/components/context.jsonld +302 -51
  73. package/dist/http/search/SearchHttpHandler.js +8 -8
  74. package/dist/http/search/SearchHttpHandler.js.map +1 -1
  75. package/dist/identity/drizzle/PodLookupRepository.d.ts +11 -1
  76. package/dist/identity/drizzle/PodLookupRepository.js +95 -4
  77. package/dist/identity/drizzle/PodLookupRepository.js.map +1 -1
  78. package/dist/identity/drizzle/db.js +4 -43
  79. package/dist/identity/drizzle/db.js.map +1 -1
  80. package/dist/identity/drizzle/schema.pg.d.ts +0 -5
  81. package/dist/identity/drizzle/schema.pg.js +2 -16
  82. package/dist/identity/drizzle/schema.pg.js.map +1 -1
  83. package/dist/identity/drizzle/schema.sqlite.d.ts +19 -176
  84. package/dist/identity/drizzle/schema.sqlite.js +2 -16
  85. package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
  86. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.d.ts +4 -4
  87. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +7 -7
  88. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
  89. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld +6 -6
  90. package/dist/identity/oidc/AutoDetectOidcHandler.d.ts +4 -4
  91. package/dist/identity/oidc/AutoDetectOidcHandler.js +6 -6
  92. package/dist/identity/oidc/AutoDetectOidcHandler.js.map +1 -1
  93. package/dist/identity/oidc/AutoDetectOidcHandler.jsonld +6 -6
  94. package/dist/identity/oidc/ScopedPickWebIdHandler.d.ts +37 -0
  95. package/dist/identity/oidc/ScopedPickWebIdHandler.js +211 -0
  96. package/dist/identity/oidc/ScopedPickWebIdHandler.js.map +1 -0
  97. package/dist/identity/oidc/ScopedPickWebIdHandler.jsonld +158 -0
  98. package/dist/index.d.ts +12 -2
  99. package/dist/index.js +16 -4
  100. package/dist/index.js.map +1 -1
  101. package/dist/main.js +8 -2
  102. package/dist/main.js.map +1 -1
  103. package/dist/provision/ProvisionPodCreator.d.ts +3 -4
  104. package/dist/provision/ProvisionPodCreator.js +8 -13
  105. package/dist/provision/ProvisionPodCreator.js.map +1 -1
  106. package/dist/provision/ProvisionPodCreator.jsonld +7 -7
  107. package/dist/runtime/Proxy.d.ts +0 -1
  108. package/dist/runtime/Proxy.js +0 -9
  109. package/dist/runtime/Proxy.js.map +1 -1
  110. package/dist/runtime/bootstrap.d.ts +1 -0
  111. package/dist/runtime/bootstrap.js +5 -2
  112. package/dist/runtime/bootstrap.js.map +1 -1
  113. package/dist/runtime/css-process.d.ts +12 -4
  114. package/dist/runtime/css-process.js +61 -14
  115. package/dist/runtime/css-process.js.map +1 -1
  116. package/dist/runtime/oidc-issuer.d.ts +3 -2
  117. package/dist/runtime/oidc-issuer.js +3 -2
  118. package/dist/runtime/oidc-issuer.js.map +1 -1
  119. package/dist/runtime/runtime-types.d.ts +1 -0
  120. package/dist/runtime/runtime-types.js.map +1 -1
  121. package/dist/solidfs/LocalFirstRdfRepresentationResolver.d.ts +21 -0
  122. package/dist/solidfs/LocalFirstRdfRepresentationResolver.js +38 -0
  123. package/dist/solidfs/LocalFirstRdfRepresentationResolver.js.map +1 -0
  124. package/dist/solidfs/LocalSolidFS.d.ts +18 -0
  125. package/dist/solidfs/LocalSolidFS.js +539 -0
  126. package/dist/solidfs/LocalSolidFS.js.map +1 -0
  127. package/dist/solidfs/PodSolidFsHttpClient.d.ts +16 -0
  128. package/dist/solidfs/PodSolidFsHttpClient.js +93 -0
  129. package/dist/solidfs/PodSolidFsHttpClient.js.map +1 -0
  130. package/dist/solidfs/PodSolidFsHydrator.d.ts +27 -0
  131. package/dist/solidfs/PodSolidFsHydrator.js +127 -0
  132. package/dist/solidfs/PodSolidFsHydrator.js.map +1 -0
  133. package/dist/solidfs/PodSolidFsSyncer.d.ts +21 -0
  134. package/dist/solidfs/PodSolidFsSyncer.js +78 -0
  135. package/dist/solidfs/PodSolidFsSyncer.js.map +1 -0
  136. package/dist/solidfs/RdfIndexSolidFsSyncer.d.ts +22 -0
  137. package/dist/solidfs/RdfIndexSolidFsSyncer.js +131 -0
  138. package/dist/solidfs/RdfIndexSolidFsSyncer.js.map +1 -0
  139. package/dist/solidfs/index.d.ts +7 -0
  140. package/dist/solidfs/index.js +24 -0
  141. package/dist/solidfs/index.js.map +1 -0
  142. package/dist/solidfs/types.d.ts +131 -0
  143. package/dist/solidfs/types.js +19 -0
  144. package/dist/solidfs/types.js.map +1 -0
  145. package/dist/storage/RepresentationPartialConvertingStore.js +6 -13
  146. package/dist/storage/RepresentationPartialConvertingStore.js.map +1 -1
  147. package/dist/storage/SparqlUpdateResourceStore.d.ts +4 -0
  148. package/dist/storage/SparqlUpdateResourceStore.js +13 -0
  149. package/dist/storage/SparqlUpdateResourceStore.js.map +1 -1
  150. package/dist/storage/SparqlUpdateResourceStore.jsonld +26 -0
  151. package/dist/storage/accessors/MinioDataAccessor.d.ts +2 -0
  152. package/dist/storage/accessors/MinioDataAccessor.js +13 -7
  153. package/dist/storage/accessors/MinioDataAccessor.js.map +1 -1
  154. package/dist/storage/accessors/MinioDataAccessor.jsonld +8 -0
  155. package/dist/storage/accessors/MixDataAccessor.d.ts +85 -4
  156. package/dist/storage/accessors/MixDataAccessor.js +511 -16
  157. package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
  158. package/dist/storage/accessors/MixDataAccessor.jsonld +176 -1
  159. package/dist/storage/accessors/QuintStoreSparqlDataAccessor.d.ts +7 -0
  160. package/dist/storage/accessors/QuintStoreSparqlDataAccessor.js +72 -4
  161. package/dist/storage/accessors/QuintStoreSparqlDataAccessor.js.map +1 -1
  162. package/dist/storage/accessors/QuintStoreSparqlDataAccessor.jsonld +24 -0
  163. package/dist/storage/quint/BaseQuintStore.d.ts +3 -0
  164. package/dist/storage/quint/BaseQuintStore.js +51 -27
  165. package/dist/storage/quint/BaseQuintStore.js.map +1 -1
  166. package/dist/storage/quint/PgQuintStore.d.ts +1 -0
  167. package/dist/storage/quint/PgQuintStore.js +50 -32
  168. package/dist/storage/quint/PgQuintStore.js.map +1 -1
  169. package/dist/storage/quint/PgQuintStore.jsonld +4 -3
  170. package/dist/storage/quint/SqliteQuintStore.d.ts +5 -0
  171. package/dist/storage/quint/SqliteQuintStore.js +100 -0
  172. package/dist/storage/quint/SqliteQuintStore.js.map +1 -1
  173. package/dist/storage/quint/SqliteQuintStore.jsonld +20 -0
  174. package/dist/storage/quint/types.d.ts +16 -0
  175. package/dist/storage/quint/types.js.map +1 -1
  176. package/dist/storage/rdf/Rdf3xTripleIndex.d.ts +55 -0
  177. package/dist/storage/rdf/Rdf3xTripleIndex.js +1235 -0
  178. package/dist/storage/rdf/Rdf3xTripleIndex.js.map +1 -0
  179. package/dist/storage/rdf/RdfContentTypes.d.ts +9 -0
  180. package/dist/storage/rdf/RdfContentTypes.js +79 -0
  181. package/dist/storage/rdf/RdfContentTypes.js.map +1 -0
  182. package/dist/storage/rdf/RdfLocalQueryEngine.d.ts +76 -0
  183. package/dist/storage/rdf/RdfLocalQueryEngine.js +2636 -0
  184. package/dist/storage/rdf/RdfLocalQueryEngine.js.map +1 -0
  185. package/dist/storage/rdf/RdfQuadIndex.d.ts +98 -0
  186. package/dist/storage/rdf/RdfQuadIndex.js +1840 -0
  187. package/dist/storage/rdf/RdfQuadIndex.js.map +1 -0
  188. package/dist/storage/rdf/RdfQuadIndex.jsonld +416 -0
  189. package/dist/storage/rdf/RdfShadowComparator.d.ts +12 -0
  190. package/dist/storage/rdf/RdfShadowComparator.js +47 -0
  191. package/dist/storage/rdf/RdfShadowComparator.js.map +1 -0
  192. package/dist/storage/rdf/RdfSparqlAdapter.d.ts +147 -0
  193. package/dist/storage/rdf/RdfSparqlAdapter.js +2420 -0
  194. package/dist/storage/rdf/RdfSparqlAdapter.js.map +1 -0
  195. package/dist/storage/rdf/RdfSparqlAdapter.jsonld +414 -0
  196. package/dist/storage/rdf/RdfTermDictionary.d.ts +27 -0
  197. package/dist/storage/rdf/RdfTermDictionary.js +352 -0
  198. package/dist/storage/rdf/RdfTermDictionary.js.map +1 -0
  199. package/dist/storage/rdf/RdfTermDictionary.jsonld +114 -0
  200. package/dist/storage/rdf/RdfTermSemantics.d.ts +6 -0
  201. package/dist/storage/rdf/RdfTermSemantics.js +40 -0
  202. package/dist/storage/rdf/RdfTermSemantics.js.map +1 -0
  203. package/dist/storage/rdf/RdfTextIndex.d.ts +23 -0
  204. package/dist/storage/rdf/RdfTextIndex.js +569 -0
  205. package/dist/storage/rdf/RdfTextIndex.js.map +1 -0
  206. package/dist/storage/rdf/RdfVectorIndex.d.ts +22 -0
  207. package/dist/storage/rdf/RdfVectorIndex.js +631 -0
  208. package/dist/storage/rdf/RdfVectorIndex.js.map +1 -0
  209. package/dist/storage/rdf/RdfXmlSerializer.d.ts +2 -0
  210. package/dist/storage/rdf/RdfXmlSerializer.js +123 -0
  211. package/dist/storage/rdf/RdfXmlSerializer.js.map +1 -0
  212. package/dist/storage/rdf/ShadowRdfQuintStore.d.ts +58 -0
  213. package/dist/storage/rdf/ShadowRdfQuintStore.js +202 -0
  214. package/dist/storage/rdf/ShadowRdfQuintStore.js.map +1 -0
  215. package/dist/storage/rdf/ShadowRdfQuintStore.jsonld +308 -0
  216. package/dist/storage/rdf/SolidRdfEngine.d.ts +51 -0
  217. package/dist/storage/rdf/SolidRdfEngine.js +264 -0
  218. package/dist/storage/rdf/SolidRdfEngine.js.map +1 -0
  219. package/dist/storage/rdf/SolidRdfEngine.jsonld +338 -0
  220. package/dist/storage/rdf/SolidRdfSparqlEngine.d.ts +92 -0
  221. package/dist/storage/rdf/SolidRdfSparqlEngine.js +477 -0
  222. package/dist/storage/rdf/SolidRdfSparqlEngine.js.map +1 -0
  223. package/dist/storage/rdf/SolidRdfSparqlEngine.jsonld +257 -0
  224. package/dist/storage/rdf/index.d.ts +15 -0
  225. package/dist/storage/rdf/index.js +61 -0
  226. package/dist/storage/rdf/index.js.map +1 -0
  227. package/dist/storage/rdf/models-benchmark.d.ts +260 -0
  228. package/dist/storage/rdf/models-benchmark.js +1405 -0
  229. package/dist/storage/rdf/models-benchmark.js.map +1 -0
  230. package/dist/storage/rdf/types.d.ts +726 -0
  231. package/dist/storage/rdf/types.js +3 -0
  232. package/dist/storage/rdf/types.js.map +1 -0
  233. package/dist/storage/rdf/types.jsonld +316 -0
  234. package/dist/storage/vector/VectorIndexingListener.d.ts +5 -5
  235. package/dist/storage/vector/VectorIndexingListener.js +19 -19
  236. package/dist/storage/vector/VectorIndexingListener.js.map +1 -1
  237. package/package.json +3 -2
  238. package/templates/pod/acp/.acr.hbs +39 -0
  239. package/templates/pod/acp/README.acr +18 -0
  240. package/templates/pod/acp/profile/card.acr +22 -0
  241. package/templates/pod/base/README$.md.hbs +27 -0
  242. package/templates/pod/base/profile/card$.ttl.hbs +13 -0
  243. package/templates/pod/wac/.acl.hbs +26 -0
  244. package/templates/pod/wac/README.acl.hbs +14 -0
  245. package/templates/pod/wac/profile/card.acl.hbs +19 -0
  246. package/dist/api/handlers/WebIdProfileHandler.d.ts +0 -16
  247. package/dist/api/handlers/WebIdProfileHandler.js +0 -423
  248. package/dist/api/handlers/WebIdProfileHandler.js.map +0 -1
  249. package/dist/identity/drizzle/WebIdProfileRepository.d.ts +0 -63
  250. package/dist/identity/drizzle/WebIdProfileRepository.js +0 -168
  251. package/dist/identity/drizzle/WebIdProfileRepository.js.map +0 -1
  252. package/dist/identity/drizzle/WebIdProfileRepository.jsonld +0 -112
  253. package/dist/storage/quint/BaseQuintStore.jsonld +0 -257
@@ -1,23 +1,39 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.MixDataAccessor = void 0;
7
+ const stream_1 = require("stream");
4
8
  const global_logger_factory_1 = require("global-logger-factory");
9
+ const arrayify_stream_1 = __importDefault(require("arrayify-stream"));
10
+ const n3_1 = require("n3");
11
+ const jsonld_1 = __importDefault(require("jsonld"));
12
+ const rdf_parse_1 = require("rdf-parse");
5
13
  const community_server_1 = require("@solid/community-server");
14
+ const RdfSparqlAdapter_1 = require("../rdf/RdfSparqlAdapter");
15
+ const RdfContentTypes_1 = require("../rdf/RdfContentTypes");
16
+ const RdfQuadIndex_1 = require("../rdf/RdfQuadIndex");
17
+ const RdfXmlSerializer_1 = require("../rdf/RdfXmlSerializer");
18
+ const SolidRdfEngine_1 = require("../rdf/SolidRdfEngine");
6
19
  const MetadataRequestContext_1 = require("../MetadataRequestContext");
7
20
  /**
8
21
  * MixDataAccessor - Routes data to appropriate storage based on content type
9
22
  *
10
23
  * - RDF data (internal/quads) -> structuredDataAccessor (Quadstore or QuintStore)
24
+ * - RDF file mirrors (.ttl/.jsonld) -> rdfFileDataAccessor (local FileSystem)
11
25
  * - Other data (binary, text, etc.) -> unstructuredDataAccessor (FileSystem, Minio, etc.)
12
26
  *
13
27
  * This uses composition instead of inheritance, allowing any DataAccessor
14
28
  * to be used as the RDF storage backend.
15
29
  */
16
30
  class MixDataAccessor {
17
- constructor(structuredDataAccessor, unstructuredDataAccessor, presignedRedirectEnabled = false, mirrorContainersToUnstructured = true) {
31
+ constructor(structuredDataAccessor, unstructuredDataAccessor, presignedRedirectEnabled = false, mirrorContainersToUnstructured = true, rdfFileDataAccessor = unstructuredDataAccessor) {
18
32
  this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
33
+ this.rdfSparqlAdapter = new RdfSparqlAdapter_1.RdfSparqlAdapter();
19
34
  this.structuredDataAccessor = structuredDataAccessor;
20
35
  this.unstructuredDataAccessor = unstructuredDataAccessor;
36
+ this.rdfFileDataAccessor = rdfFileDataAccessor;
21
37
  this.presignedRedirectEnabled = presignedRedirectEnabled;
22
38
  this.mirrorContainersToUnstructured = mirrorContainersToUnstructured;
23
39
  }
@@ -50,6 +66,51 @@ class MixDataAccessor {
50
66
  }
51
67
  return await this.structuredDataAccessor.getData(identifier);
52
68
  }
69
+ /**
70
+ * Read the local RDF file mirror used by SolidFS/local-first HTTP reads.
71
+ *
72
+ * `getData()` intentionally keeps returning the structured quad stream for
73
+ * CSS internals. This method is the explicit file-content path for callers
74
+ * that need a real Turtle/JSON-LD byte stream.
75
+ */
76
+ async getLocalRdfDocument(identifier) {
77
+ if ((0, community_server_1.isContainerIdentifier)(identifier)) {
78
+ throw new community_server_1.NotFoundHttpError();
79
+ }
80
+ if (this.isByLineRdfIdentifier(identifier)) {
81
+ try {
82
+ return {
83
+ data: await this.rdfFileDataAccessor.getData(identifier),
84
+ metadata: await this.getExistingLocalRdfMetadata(identifier),
85
+ };
86
+ }
87
+ catch (error) {
88
+ if (!community_server_1.NotFoundHttpError.isInstance(error)) {
89
+ throw error;
90
+ }
91
+ }
92
+ }
93
+ const metadata = await this.getMetadata(identifier);
94
+ if (!this.isLocalMirroredRdf(identifier, metadata)) {
95
+ throw new community_server_1.NotFoundHttpError();
96
+ }
97
+ try {
98
+ return {
99
+ data: await this.rdfFileDataAccessor.getData(identifier),
100
+ metadata: await this.getLocalRdfMetadata(identifier, metadata),
101
+ };
102
+ }
103
+ catch (error) {
104
+ if (!community_server_1.NotFoundHttpError.isInstance(error)) {
105
+ throw error;
106
+ }
107
+ }
108
+ await this.refreshLocalRdfMirror(identifier);
109
+ return {
110
+ data: await this.rdfFileDataAccessor.getData(identifier),
111
+ metadata: await this.getLocalRdfMetadata(identifier, metadata),
112
+ };
113
+ }
53
114
  async getMetadata(identifier) {
54
115
  const cache = MetadataRequestContext_1.metadataRequestContext.getStore()?.metadataCache;
55
116
  const cacheKey = identifier.path;
@@ -92,7 +153,7 @@ class MixDataAccessor {
92
153
  this.invalidateMetadataCache(identifier);
93
154
  return;
94
155
  }
95
- await this.structuredDataAccessor.writeDocument(identifier, data, metadata);
156
+ await this.writeRdfDocument(identifier, data, metadata);
96
157
  this.invalidateMetadataCache(identifier);
97
158
  }
98
159
  async writeMetadata(identifier, metadata) {
@@ -102,32 +163,388 @@ class MixDataAccessor {
102
163
  }
103
164
  async deleteResource(identifier) {
104
165
  const metadata = await this.getMetadata(identifier);
105
- // Try to delete from unstructured storage if applicable
106
- if (this.isUnstructured(metadata)) {
107
- try {
108
- await this.unstructuredDataAccessor.deleteResource(identifier);
109
- }
110
- catch (error) {
111
- // Ignore file not found errors
112
- if (error.code !== 'ENOENT' && error.code !== 'ENOTDIR') {
113
- throw error;
114
- }
115
- }
166
+ // RDF by-line resources are mirrored to local file storage so shell tools
167
+ // can operate on real files; remove that mirror together with the index.
168
+ if (this.isLocalMirroredRdf(identifier, metadata)) {
169
+ await this.deleteRdfFileResourceIfPresent(identifier);
170
+ }
171
+ else if (this.isUnstructured(metadata)) {
172
+ await this.deleteUnstructuredResourceIfPresent(identifier);
116
173
  }
117
174
  // Always delete from structured storage (contains metadata)
118
175
  await this.structuredDataAccessor.deleteResource(identifier);
119
176
  this.invalidateMetadataCache(identifier);
120
177
  }
121
178
  /**
122
- * Execute SPARQL UPDATE on structured data accessor.
123
- * Delegates to the underlying structuredDataAccessor if it supports SPARQL.
179
+ * Execute SPARQL UPDATE.
180
+ *
181
+ * Supported embedded deltas patch the local RDF authority file first and then
182
+ * rebuild the structured RDF index. Unsupported shapes keep using the
183
+ * compatibility accessor until the embedded engine covers them.
124
184
  */
125
185
  async executeSparqlUpdate(query, baseIri) {
186
+ if (baseIri) {
187
+ const identifier = { path: baseIri };
188
+ if (this.isByLineRdfIdentifier(identifier)) {
189
+ try {
190
+ await this.executeLocalRdfSparqlUpdate(query, identifier);
191
+ this.invalidateMetadataCache(identifier);
192
+ return;
193
+ }
194
+ catch (error) {
195
+ if (!(error instanceof RdfSparqlAdapter_1.UnsupportedSparqlQueryError)) {
196
+ throw error;
197
+ }
198
+ }
199
+ }
200
+ }
126
201
  const accessor = this.structuredDataAccessor;
127
202
  if (typeof accessor.executeSparqlUpdate !== 'function') {
128
203
  throw new Error('Structured data accessor does not support SPARQL UPDATE');
129
204
  }
130
- return accessor.executeSparqlUpdate(query, baseIri);
205
+ await accessor.executeSparqlUpdate(query, baseIri);
206
+ if (baseIri) {
207
+ const identifier = { path: baseIri };
208
+ await this.refreshLocalRdfMirror(identifier);
209
+ this.invalidateMetadataCache(identifier);
210
+ }
211
+ }
212
+ async executeLocalRdfSparqlUpdate(query, identifier) {
213
+ const delta = this.rdfSparqlAdapter.compileUpdateDelta(query, identifier.path);
214
+ this.assertLocalRdfDeltaTargetsGraph(delta.operations, identifier.path);
215
+ const existingText = await this.readLocalRdfTextOrEmpty(identifier);
216
+ const graph = n3_1.DataFactory.namedNode(identifier.path);
217
+ const existingQuads = existingText.length > 0
218
+ ? await this.parseLocalRdf(identifier, existingText, this.localRdfContentType(identifier))
219
+ .then((quads) => quads.map((quad) => this.toGraphQuad(quad, graph)))
220
+ : [];
221
+ const nextQuads = this.applyLocalRdfDelta(existingQuads, delta.operations);
222
+ const authorityQuads = nextQuads.map((quad) => this.toDefaultGraphQuad(quad));
223
+ await this.writeLocalRdfAuthority(identifier, authorityQuads);
224
+ await this.writeStructuredRdfIndex(identifier, authorityQuads, new community_server_1.RepresentationMetadata(identifier));
225
+ }
226
+ applyLocalRdfDelta(quads, operations) {
227
+ const byKey = new Map(quads.map((quad) => [this.quadKey(quad), quad]));
228
+ for (const operation of operations) {
229
+ if (operation.type === 'insert') {
230
+ for (const quad of operation.quads) {
231
+ byKey.set(this.quadKey(quad), quad);
232
+ }
233
+ continue;
234
+ }
235
+ if (operation.type === 'delete') {
236
+ for (const quad of operation.quads) {
237
+ byKey.delete(this.quadKey(quad));
238
+ }
239
+ continue;
240
+ }
241
+ if (operation.type === 'insertDeleteWhere') {
242
+ const rows = this.queryLocalUpdateBindings([...byKey.values()], operation.query);
243
+ for (const quad of this.rdfSparqlAdapter.materializeDeleteWhere(operation.deletes, rows)) {
244
+ byKey.delete(this.quadKey(quad));
245
+ }
246
+ for (const quad of this.rdfSparqlAdapter.materializeDeleteWhere(operation.inserts, rows)) {
247
+ byKey.set(this.quadKey(quad), quad);
248
+ }
249
+ continue;
250
+ }
251
+ if (operation.type === 'insertWhere') {
252
+ const rows = this.queryLocalUpdateBindings([...byKey.values()], operation.query);
253
+ for (const quad of this.rdfSparqlAdapter.materializeDeleteWhere(operation.inserts, rows)) {
254
+ byKey.set(this.quadKey(quad), quad);
255
+ }
256
+ continue;
257
+ }
258
+ const rows = this.queryLocalUpdateBindings([...byKey.values()], operation.query);
259
+ for (const quad of this.rdfSparqlAdapter.materializeDeleteWhere(operation.template, rows)) {
260
+ byKey.delete(this.quadKey(quad));
261
+ }
262
+ }
263
+ return [...byKey.values()];
264
+ }
265
+ assertLocalRdfDeltaTargetsGraph(operations, graphIri) {
266
+ for (const operation of operations) {
267
+ const graphTerms = operation.type === 'deleteWhere'
268
+ ? operation.template.map((item) => item.graph)
269
+ : operation.type === 'insertDeleteWhere'
270
+ ? [
271
+ ...operation.deletes.map((item) => item.graph),
272
+ ...operation.inserts.map((item) => item.graph),
273
+ ...this.queryGraphTerms(operation.query),
274
+ ]
275
+ : operation.type === 'insertWhere'
276
+ ? [
277
+ ...operation.inserts.map((item) => item.graph),
278
+ ...this.queryGraphTerms(operation.query),
279
+ ]
280
+ : operation.quads.map((quad) => quad.graph);
281
+ for (const graph of graphTerms) {
282
+ if (!('termType' in graph) || graph.termType !== 'NamedNode' || graph.value !== graphIri) {
283
+ throw new RdfSparqlAdapter_1.UnsupportedSparqlQueryError('Embedded local RDF update only supports the target document graph');
284
+ }
285
+ }
286
+ }
287
+ }
288
+ queryLocalUpdateBindings(quads, query) {
289
+ const index = new RdfQuadIndex_1.RdfQuadIndex({ path: ':memory:' });
290
+ index.open();
291
+ try {
292
+ const engine = new SolidRdfEngine_1.SolidRdfEngine({ index });
293
+ engine.put(quads);
294
+ return engine.query(query).bindings;
295
+ }
296
+ finally {
297
+ index.close();
298
+ }
299
+ }
300
+ queryGraphTerms(query) {
301
+ const patterns = [...query.patterns];
302
+ for (const optional of query.optional ?? []) {
303
+ patterns.push(...(Array.isArray(optional) ? optional : optional.patterns));
304
+ }
305
+ for (const union of query.unions ?? []) {
306
+ for (const branch of union.branches) {
307
+ patterns.push(...branch.patterns);
308
+ for (const optional of branch.optional ?? []) {
309
+ patterns.push(...(Array.isArray(optional) ? optional : optional.patterns));
310
+ }
311
+ }
312
+ }
313
+ return patterns.flatMap((pattern) => pattern.graph ? [pattern.graph] : []);
314
+ }
315
+ async readLocalRdfTextOrEmpty(identifier) {
316
+ try {
317
+ return await this.readStreamText(await this.rdfFileDataAccessor.getData(identifier));
318
+ }
319
+ catch (error) {
320
+ if (community_server_1.NotFoundHttpError.isInstance(error)) {
321
+ await this.refreshLocalRdfMirror(identifier);
322
+ try {
323
+ return await this.readStreamText(await this.rdfFileDataAccessor.getData(identifier));
324
+ }
325
+ catch (retryError) {
326
+ if (community_server_1.NotFoundHttpError.isInstance(retryError)) {
327
+ return '';
328
+ }
329
+ throw retryError;
330
+ }
331
+ }
332
+ throw error;
333
+ }
334
+ }
335
+ async writeLocalRdfAuthority(identifier, quads) {
336
+ await this.ensureRdfFileParentContainers(identifier);
337
+ await this.rdfFileDataAccessor.writeDocument(identifier, (0, community_server_1.guardStream)(stream_1.Readable.from([await this.serializeQuadsForLocalFile(identifier, quads)])), this.createLocalRdfMetadata(identifier, new community_server_1.RepresentationMetadata(identifier)));
338
+ }
339
+ toDefaultGraphQuad(quad) {
340
+ return n3_1.DataFactory.quad(quad.subject, quad.predicate, quad.object);
341
+ }
342
+ toGraphQuad(quad, graph) {
343
+ return n3_1.DataFactory.quad(quad.subject, quad.predicate, quad.object, graph);
344
+ }
345
+ quadKey(quad) {
346
+ return [quad.graph, quad.subject, quad.predicate, quad.object]
347
+ .map((term) => (0, n3_1.termToId)(term))
348
+ .join('\u001f');
349
+ }
350
+ /**
351
+ * Rebuild the structured RDF index from an already-written local RDF file.
352
+ *
353
+ * SolidFS uses this after tools edit `.ttl`/`.jsonld` files directly. The
354
+ * local file remains the content authority; the structured accessor is only
355
+ * refreshed as query/index state.
356
+ */
357
+ async syncLocalRdfDocument(identifier, data, contentType, options) {
358
+ if (!this.isRdfDocumentIdentifier(identifier)) {
359
+ throw new Error(`Cannot sync non RDF document into RDF index: ${identifier.path}`);
360
+ }
361
+ const source = data ?? await this.rdfFileDataAccessor.getData(identifier);
362
+ const localContentType = contentType ?? this.localRdfContentType(identifier);
363
+ const text = await this.readStreamText(source);
364
+ if (data) {
365
+ await this.ensureRdfFileParentContainers(identifier);
366
+ await this.rdfFileDataAccessor.writeDocument(identifier, (0, community_server_1.guardStream)(stream_1.Readable.from([text])), this.createLocalRdfMetadata(identifier, new community_server_1.RepresentationMetadata(identifier)));
367
+ }
368
+ const quads = await this.parseLocalRdf(identifier, text, localContentType);
369
+ await this.writeStructuredRdfIndex(identifier, quads, new community_server_1.RepresentationMetadata(identifier), {
370
+ ...options,
371
+ contentType: localContentType,
372
+ });
373
+ this.invalidateMetadataCache(identifier);
374
+ }
375
+ async deleteLocalRdfIndex(identifier) {
376
+ try {
377
+ const sourceScopedAccessor = this.sourceScopedStructuredAccessor();
378
+ if (sourceScopedAccessor) {
379
+ await sourceScopedAccessor.deleteRdfSourceDocument(identifier);
380
+ }
381
+ else {
382
+ await this.structuredDataAccessor.deleteResource(identifier);
383
+ }
384
+ this.invalidateMetadataCache(identifier);
385
+ }
386
+ catch (error) {
387
+ if (!community_server_1.NotFoundHttpError.isInstance(error)) {
388
+ throw error;
389
+ }
390
+ }
391
+ }
392
+ async writeRdfDocument(identifier, data, metadata) {
393
+ const quads = await (0, arrayify_stream_1.default)(data);
394
+ const structuredMetadata = new community_server_1.RepresentationMetadata(metadata);
395
+ (0, community_server_1.addResourceMetadata)(structuredMetadata, false);
396
+ (0, community_server_1.updateModifiedDate)(structuredMetadata);
397
+ await this.ensureRdfFileParentContainers(identifier);
398
+ await this.rdfFileDataAccessor.writeDocument(identifier, (0, community_server_1.guardStream)(stream_1.Readable.from([await this.serializeQuadsForLocalFile(identifier, quads)])), this.createLocalRdfMetadata(identifier, metadata));
399
+ try {
400
+ await this.writeStructuredRdfIndex(identifier, quads, structuredMetadata);
401
+ }
402
+ catch (error) {
403
+ await this.deleteRdfFileResourceIfPresent(identifier);
404
+ throw error;
405
+ }
406
+ }
407
+ async writeStructuredRdfIndex(identifier, quads, metadata, options = {}) {
408
+ const structuredMetadata = new community_server_1.RepresentationMetadata(metadata);
409
+ (0, community_server_1.addResourceMetadata)(structuredMetadata, false);
410
+ (0, community_server_1.updateModifiedDate)(structuredMetadata);
411
+ const sourceScopedAccessor = this.sourceScopedStructuredAccessor();
412
+ if (sourceScopedAccessor) {
413
+ await sourceScopedAccessor.writeRdfSourceDocument(identifier, quads, structuredMetadata, this.rdfSourceInput(identifier, options));
414
+ return;
415
+ }
416
+ await this.structuredDataAccessor.writeDocument(identifier, (0, community_server_1.guardStream)(stream_1.Readable.from(quads)), structuredMetadata);
417
+ }
418
+ async refreshLocalRdfMirror(identifier) {
419
+ let metadata;
420
+ let quads;
421
+ try {
422
+ metadata = await this.structuredDataAccessor.getMetadata(identifier);
423
+ if (!this.isLocalMirroredRdf(identifier, metadata)) {
424
+ return;
425
+ }
426
+ quads = await (0, arrayify_stream_1.default)(await this.structuredDataAccessor.getData(identifier));
427
+ }
428
+ catch (error) {
429
+ if (community_server_1.NotFoundHttpError.isInstance(error)) {
430
+ await this.deleteRdfFileResourceIfPresent(identifier);
431
+ return;
432
+ }
433
+ throw error;
434
+ }
435
+ await this.ensureRdfFileParentContainers(identifier);
436
+ await this.rdfFileDataAccessor.writeDocument(identifier, (0, community_server_1.guardStream)(stream_1.Readable.from([await this.serializeQuadsForLocalFile(identifier, quads)])), this.createLocalRdfMetadata(identifier, metadata));
437
+ }
438
+ async getLocalRdfMetadata(identifier, sourceMetadata) {
439
+ try {
440
+ return await this.getExistingLocalRdfMetadata(identifier);
441
+ }
442
+ catch (error) {
443
+ if (!community_server_1.NotFoundHttpError.isInstance(error)) {
444
+ throw error;
445
+ }
446
+ return this.createLocalRdfMetadata(identifier, sourceMetadata);
447
+ }
448
+ }
449
+ async getExistingLocalRdfMetadata(identifier) {
450
+ const metadata = await this.rdfFileDataAccessor.getMetadata(identifier);
451
+ metadata.contentType = this.localRdfContentType(identifier);
452
+ return metadata;
453
+ }
454
+ createLocalRdfMetadata(identifier, metadata) {
455
+ const localMetadata = new community_server_1.RepresentationMetadata(metadata);
456
+ localMetadata.contentType = this.localRdfContentType(identifier);
457
+ return localMetadata;
458
+ }
459
+ localRdfContentType(identifier) {
460
+ return (0, RdfContentTypes_1.rdfContentTypeForPath)(identifier.path) ?? 'text/turtle';
461
+ }
462
+ sourceScopedStructuredAccessor() {
463
+ const accessor = this.structuredDataAccessor;
464
+ if (typeof accessor.writeRdfSourceDocument === 'function'
465
+ && typeof accessor.deleteRdfSourceDocument === 'function') {
466
+ return accessor;
467
+ }
468
+ return undefined;
469
+ }
470
+ rdfSourceInput(identifier, options) {
471
+ const workspace = options.workspace ?? this.parentContainer(identifier).path;
472
+ return {
473
+ source: options.source ?? identifier.path,
474
+ workspace,
475
+ localPath: options.localPath ?? this.relativePathFromWorkspace(identifier.path, workspace),
476
+ contentType: options.contentType ?? this.localRdfContentType(identifier),
477
+ sourceVersion: options.sourceVersion,
478
+ };
479
+ }
480
+ relativePathFromWorkspace(identifierPath, workspaceValue) {
481
+ try {
482
+ const resource = new URL(identifierPath);
483
+ const workspace = new URL(workspaceValue.endsWith('/') ? workspaceValue : `${workspaceValue}/`);
484
+ if (resource.origin !== workspace.origin || !resource.pathname.startsWith(workspace.pathname)) {
485
+ return undefined;
486
+ }
487
+ return decodeURIComponent(resource.pathname.slice(workspace.pathname.length));
488
+ }
489
+ catch {
490
+ return undefined;
491
+ }
492
+ }
493
+ isByLineRdfIdentifier(identifier) {
494
+ return (0, RdfContentTypes_1.isLineAddressableRdfPath)(identifier.path);
495
+ }
496
+ isRdfDocumentIdentifier(identifier) {
497
+ return (0, RdfContentTypes_1.isRdfDocumentPath)(identifier.path);
498
+ }
499
+ isLocalMirroredRdf(identifier, metadata) {
500
+ return metadata.contentType === community_server_1.INTERNAL_QUADS || this.isRdfDocumentIdentifier(identifier);
501
+ }
502
+ async serializeQuadsForLocalFile(identifier, quads) {
503
+ if (this.localRdfContentType(identifier) === 'application/ld+json') {
504
+ const nquads = await this.serializeNQuads(quads);
505
+ const document = await jsonld_1.default.fromRDF(nquads, { format: 'application/n-quads' });
506
+ return `${JSON.stringify(document, null, 2)}\n`;
507
+ }
508
+ if (this.localRdfContentType(identifier) === 'application/rdf+xml') {
509
+ return (0, RdfXmlSerializer_1.serializeRdfXml)(quads);
510
+ }
511
+ const writer = new n3_1.Writer({ format: this.localRdfContentType(identifier) });
512
+ return writer.quadsToString(quads);
513
+ }
514
+ async serializeNQuads(quads) {
515
+ return new Promise((resolve, reject) => {
516
+ const writer = new n3_1.Writer({ format: 'application/n-quads' });
517
+ writer.addQuads(quads);
518
+ writer.end((error, result) => {
519
+ if (error) {
520
+ reject(error);
521
+ return;
522
+ }
523
+ resolve(result);
524
+ });
525
+ });
526
+ }
527
+ async parseLocalRdf(identifier, text, contentType) {
528
+ if (contentType === 'application/ld+json') {
529
+ const nquads = await jsonld_1.default.toRDF(JSON.parse(text), {
530
+ base: identifier.path,
531
+ format: 'application/n-quads',
532
+ });
533
+ return new n3_1.Parser({ format: 'application/n-quads', baseIRI: identifier.path }).parse(nquads);
534
+ }
535
+ if (contentType === 'application/rdf+xml') {
536
+ return (0, arrayify_stream_1.default)(rdf_parse_1.rdfParser.parse(stream_1.Readable.from([text]), {
537
+ contentType,
538
+ baseIRI: identifier.path,
539
+ }));
540
+ }
541
+ return new n3_1.Parser({ format: contentType, baseIRI: identifier.path }).parse(text);
542
+ }
543
+ async readStreamText(data) {
544
+ const chunks = await (0, arrayify_stream_1.default)(data);
545
+ return chunks
546
+ .map((chunk) => typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8'))
547
+ .join('');
131
548
  }
132
549
  /**
133
550
  * Write unstructured document: store data in unstructured accessor,
@@ -162,6 +579,84 @@ class MixDataAccessor {
162
579
  throw error;
163
580
  }
164
581
  }
582
+ async deleteUnstructuredResourceIfPresent(identifier) {
583
+ try {
584
+ await this.unstructuredDataAccessor.deleteResource(identifier);
585
+ }
586
+ catch (error) {
587
+ if (error?.code !== 'ENOENT' && error?.code !== 'ENOTDIR' && !community_server_1.NotFoundHttpError.isInstance(error)) {
588
+ throw error;
589
+ }
590
+ }
591
+ }
592
+ async deleteRdfFileResourceIfPresent(identifier) {
593
+ try {
594
+ await this.rdfFileDataAccessor.deleteResource(identifier);
595
+ }
596
+ catch (error) {
597
+ if (error?.code !== 'ENOENT' && error?.code !== 'ENOTDIR' && !community_server_1.NotFoundHttpError.isInstance(error)) {
598
+ throw error;
599
+ }
600
+ }
601
+ }
602
+ async ensureUnstructuredParentContainers(identifier) {
603
+ await this.ensureParentContainers(identifier, this.unstructuredDataAccessor);
604
+ }
605
+ async ensureRdfFileParentContainers(identifier) {
606
+ await this.ensureParentContainers(identifier, this.rdfFileDataAccessor);
607
+ }
608
+ async ensureParentContainers(identifier, accessor) {
609
+ const containers = [];
610
+ let current = this.parentContainer(identifier);
611
+ while (!this.sameIdentifier(current, identifier)) {
612
+ containers.push(current);
613
+ const next = this.parentContainer(current);
614
+ if (this.sameIdentifier(next, current)) {
615
+ break;
616
+ }
617
+ current = next;
618
+ }
619
+ for (const container of containers.reverse()) {
620
+ await this.writeContainerIfMissing(accessor, container);
621
+ }
622
+ }
623
+ async writeContainerIfMissing(accessor, identifier) {
624
+ try {
625
+ await accessor.getMetadata(identifier);
626
+ return;
627
+ }
628
+ catch (error) {
629
+ if (!community_server_1.NotFoundHttpError.isInstance(error)) {
630
+ throw error;
631
+ }
632
+ }
633
+ await accessor.writeContainer(identifier, new community_server_1.RepresentationMetadata(identifier));
634
+ }
635
+ sameIdentifier(left, right) {
636
+ return left.path === right.path;
637
+ }
638
+ parentContainer(identifier) {
639
+ try {
640
+ const url = new URL(identifier.path);
641
+ if (url.pathname === '/' || url.pathname === '') {
642
+ return { path: url.href.endsWith('/') ? url.href : `${url.href}/` };
643
+ }
644
+ const segments = url.pathname.replace(/\/+$/u, '').split('/');
645
+ segments.pop();
646
+ url.pathname = `${segments.join('/') || '/'}`.replace(/\/?$/u, '/');
647
+ url.search = '';
648
+ url.hash = '';
649
+ return { path: url.href };
650
+ }
651
+ catch {
652
+ const trimmed = identifier.path.replace(/\/+$/u, '');
653
+ const slashIndex = trimmed.lastIndexOf('/');
654
+ if (slashIndex < 0) {
655
+ return identifier;
656
+ }
657
+ return { path: `${trimmed.slice(0, slashIndex + 1)}` };
658
+ }
659
+ }
165
660
  invalidateMetadataCache(identifier) {
166
661
  const cache = MetadataRequestContext_1.metadataRequestContext.getStore()?.metadataCache;
167
662
  if (!cache) {