@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
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PodSolidFsHttpClient = void 0;
4
+ exports.resolvePodWorkspaceResourceUrl = resolvePodWorkspaceResourceUrl;
5
+ exports.solidAuthFromContext = solidAuthFromContext;
6
+ const AuthContext_1 = require("../api/auth/AuthContext");
7
+ class PodSolidFsHttpClient {
8
+ constructor(options = {}) {
9
+ this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
10
+ this.tokenEndpoint = options.tokenEndpoint ?? resolveDefaultTokenEndpoint();
11
+ }
12
+ async request(input, init) {
13
+ return this.fetchImpl(input, init);
14
+ }
15
+ async createAuthHeaders(context, operation) {
16
+ const auth = solidAuthFromContext(context);
17
+ if (!auth) {
18
+ throw new Error(`Cannot ${operation} without Solid auth context`);
19
+ }
20
+ const headers = new Headers();
21
+ if (auth.accessToken) {
22
+ headers.set('Authorization', `${auth.tokenType ?? 'Bearer'} ${auth.accessToken}`);
23
+ return headers;
24
+ }
25
+ const token = await this.exchangeClientCredentials(auth);
26
+ headers.set('Authorization', `${token.tokenType ?? 'Bearer'} ${token.accessToken}`);
27
+ return headers;
28
+ }
29
+ async exchangeClientCredentials(auth) {
30
+ if (!this.tokenEndpoint) {
31
+ throw new Error('Cannot access Pod HTTP resource with client credentials because CSS token endpoint is not configured');
32
+ }
33
+ if (!auth.clientId || !auth.clientSecret) {
34
+ throw new Error('Cannot access Pod HTTP resource without access token or Solid client credentials');
35
+ }
36
+ const response = await this.request(this.tokenEndpoint, {
37
+ method: 'POST',
38
+ headers: {
39
+ 'Content-Type': 'application/x-www-form-urlencoded',
40
+ },
41
+ body: new URLSearchParams({
42
+ grant_type: 'client_credentials',
43
+ client_id: auth.clientId,
44
+ client_secret: auth.clientSecret,
45
+ }),
46
+ });
47
+ if (!response.ok) {
48
+ throw new Error(`SolidFS token exchange failed: ${response.status} ${await response.text().catch(() => '')}`);
49
+ }
50
+ const token = await response.json();
51
+ if (!token.access_token) {
52
+ throw new Error(`SolidFS token exchange response missing access_token: ${JSON.stringify(token)}`);
53
+ }
54
+ return {
55
+ accessToken: token.access_token,
56
+ tokenType: token.token_type?.toUpperCase() === 'DPOP' ? 'DPoP' : 'Bearer',
57
+ };
58
+ }
59
+ }
60
+ exports.PodSolidFsHttpClient = PodSolidFsHttpClient;
61
+ function resolvePodWorkspaceResourceUrl(relativePath, workspace) {
62
+ try {
63
+ const base = new URL(workspace.workspace.endsWith('/') ? workspace.workspace : `${workspace.workspace}/`);
64
+ if (base.protocol !== 'http:' && base.protocol !== 'https:') {
65
+ return undefined;
66
+ }
67
+ return new URL(normalizePodRelativePath(relativePath), base).href;
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ }
73
+ function solidAuthFromContext(context) {
74
+ const auth = context?.auth;
75
+ return auth && (0, AuthContext_1.isSolidAuth)(auth) ? auth : undefined;
76
+ }
77
+ function normalizePodRelativePath(input) {
78
+ const parts = input.split(/[\\/]+/u).filter((part) => part.length > 0);
79
+ if (input.startsWith('/') || parts.length === 0 || parts.includes('..')) {
80
+ throw new Error(`Invalid Pod resource relative path: ${input}`);
81
+ }
82
+ return parts.join('/');
83
+ }
84
+ function resolveDefaultTokenEndpoint() {
85
+ if (process.env.CSS_TOKEN_ENDPOINT) {
86
+ return process.env.CSS_TOKEN_ENDPOINT;
87
+ }
88
+ if (process.env.CSS_BASE_URL) {
89
+ return new URL('.oidc/token', process.env.CSS_BASE_URL.endsWith('/') ? process.env.CSS_BASE_URL : `${process.env.CSS_BASE_URL}/`).href;
90
+ }
91
+ return undefined;
92
+ }
93
+ //# sourceMappingURL=PodSolidFsHttpClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PodSolidFsHttpClient.js","sourceRoot":"","sources":["../../src/solidfs/PodSolidFsHttpClient.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthContext, SolidAuthContext } from '../api/auth/AuthContext';\nimport { isSolidAuth } from '../api/auth/AuthContext';\nimport type { StoreContext } from '../api/chatkit/store';\nimport type { SolidFsManifest } from './types';\n\nexport interface PodSolidFsHttpClientOptions {\n fetch?: typeof fetch;\n tokenEndpoint?: string;\n}\n\nexport class PodSolidFsHttpClient {\n private readonly fetchImpl: typeof fetch;\n private readonly tokenEndpoint?: string;\n\n public constructor(options: PodSolidFsHttpClientOptions = {}) {\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.tokenEndpoint = options.tokenEndpoint ?? resolveDefaultTokenEndpoint();\n }\n\n public async request(input: string, init: RequestInit): Promise<Response> {\n return this.fetchImpl(input, init);\n }\n\n public async createAuthHeaders(context: unknown, operation: string): Promise<Headers> {\n const auth = solidAuthFromContext(context);\n if (!auth) {\n throw new Error(`Cannot ${operation} without Solid auth context`);\n }\n\n const headers = new Headers();\n if (auth.accessToken) {\n headers.set('Authorization', `${auth.tokenType ?? 'Bearer'} ${auth.accessToken}`);\n return headers;\n }\n\n const token = await this.exchangeClientCredentials(auth);\n headers.set('Authorization', `${token.tokenType ?? 'Bearer'} ${token.accessToken}`);\n return headers;\n }\n\n private async exchangeClientCredentials(auth: SolidAuthContext): Promise<{ accessToken: string; tokenType?: 'Bearer' | 'DPoP' }> {\n if (!this.tokenEndpoint) {\n throw new Error('Cannot access Pod HTTP resource with client credentials because CSS token endpoint is not configured');\n }\n if (!auth.clientId || !auth.clientSecret) {\n throw new Error('Cannot access Pod HTTP resource without access token or Solid client credentials');\n }\n const response = await this.request(this.tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: auth.clientId,\n client_secret: auth.clientSecret,\n }),\n });\n if (!response.ok) {\n throw new Error(`SolidFS token exchange failed: ${response.status} ${await response.text().catch(() => '')}`);\n }\n const token = await response.json() as { access_token?: string; token_type?: string };\n if (!token.access_token) {\n throw new Error(`SolidFS token exchange response missing access_token: ${JSON.stringify(token)}`);\n }\n return {\n accessToken: token.access_token,\n tokenType: token.token_type?.toUpperCase() === 'DPOP' ? 'DPoP' : 'Bearer',\n };\n }\n}\n\nexport function resolvePodWorkspaceResourceUrl(relativePath: string, workspace: SolidFsManifest): string | undefined {\n try {\n const base = new URL(workspace.workspace.endsWith('/') ? workspace.workspace : `${workspace.workspace}/`);\n if (base.protocol !== 'http:' && base.protocol !== 'https:') {\n return undefined;\n }\n return new URL(normalizePodRelativePath(relativePath), base).href;\n } catch {\n return undefined;\n }\n}\n\nexport function solidAuthFromContext(context: unknown): SolidAuthContext | undefined {\n const auth = (context as StoreContext | undefined)?.auth as AuthContext | undefined;\n return auth && isSolidAuth(auth) ? auth : undefined;\n}\n\nfunction normalizePodRelativePath(input: string): string {\n const parts = input.split(/[\\\\/]+/u).filter((part) => part.length > 0);\n if (input.startsWith('/') || parts.length === 0 || parts.includes('..')) {\n throw new Error(`Invalid Pod resource relative path: ${input}`);\n }\n return parts.join('/');\n}\n\nfunction resolveDefaultTokenEndpoint(): string | undefined {\n if (process.env.CSS_TOKEN_ENDPOINT) {\n return process.env.CSS_TOKEN_ENDPOINT;\n }\n if (process.env.CSS_BASE_URL) {\n return new URL('.oidc/token', process.env.CSS_BASE_URL.endsWith('/') ? process.env.CSS_BASE_URL : `${process.env.CSS_BASE_URL}/`).href;\n }\n return undefined;\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import { type SolidFsCommitHydratedInput, type SolidFsHydrateInput, type SolidFsHydrator } from './types';
2
+ export interface PodSolidFsHydratorOptions {
3
+ fetch?: typeof fetch;
4
+ tokenEndpoint?: string;
5
+ }
6
+ /**
7
+ * Hydrates object-backed Pod resources through the normal Pod HTTP boundary.
8
+ *
9
+ * The API runtime should not reach into CSS' storage container. GET/PUT/DELETE
10
+ * through CSS keeps authorization, object backends, and MixData/RDF indexing in
11
+ * one protocol path.
12
+ */
13
+ export declare class PodSolidFsHydrator implements SolidFsHydrator {
14
+ private readonly http;
15
+ constructor(options?: PodSolidFsHydratorOptions);
16
+ hydrate(input: SolidFsHydrateInput): Promise<{
17
+ contentType?: string;
18
+ sourceVersion?: string;
19
+ }>;
20
+ commit(input: SolidFsCommitHydratedInput): Promise<{
21
+ sourceVersion?: string;
22
+ }>;
23
+ delete(input: SolidFsCommitHydratedInput): Promise<void>;
24
+ private resolveResourceUrl;
25
+ private resolveChangeResourceUrl;
26
+ private responseVersion;
27
+ }
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PodSolidFsHydrator = void 0;
7
+ const node_fs_1 = require("node:fs");
8
+ const promises_1 = require("node:fs/promises");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const promises_2 = require("node:stream/promises");
11
+ const types_1 = require("./types");
12
+ const PodSolidFsHttpClient_1 = require("./PodSolidFsHttpClient");
13
+ /**
14
+ * Hydrates object-backed Pod resources through the normal Pod HTTP boundary.
15
+ *
16
+ * The API runtime should not reach into CSS' storage container. GET/PUT/DELETE
17
+ * through CSS keeps authorization, object backends, and MixData/RDF indexing in
18
+ * one protocol path.
19
+ */
20
+ class PodSolidFsHydrator {
21
+ constructor(options = {}) {
22
+ this.http = new PodSolidFsHttpClient_1.PodSolidFsHttpClient(options);
23
+ }
24
+ async hydrate(input) {
25
+ const resourceUrl = this.resolveResourceUrl(input.path, input.workspace);
26
+ const headers = await this.http.createAuthHeaders(input.context, `hydrate SolidFS object: ${resourceUrl}`);
27
+ const response = await this.http.request(resourceUrl, {
28
+ method: 'GET',
29
+ headers,
30
+ });
31
+ if (response.status === 404) {
32
+ throw new types_1.SolidFsNotFoundError(`SolidFS object not found: ${resourceUrl}`);
33
+ }
34
+ if (!response.ok) {
35
+ throw new Error(`SolidFS object hydrate failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);
36
+ }
37
+ if (!response.body) {
38
+ throw new Error(`SolidFS object hydrate failed for ${resourceUrl}: empty response body`);
39
+ }
40
+ await (0, promises_1.mkdir)(node_path_1.default.dirname(input.targetPath), { recursive: true });
41
+ await (0, promises_2.pipeline)(response.body, (0, node_fs_1.createWriteStream)(input.targetPath));
42
+ return {
43
+ contentType: response.headers.get('content-type') ?? undefined,
44
+ sourceVersion: this.responseVersion(response),
45
+ };
46
+ }
47
+ async commit(input) {
48
+ const resourceUrl = this.resolveChangeResourceUrl(input);
49
+ const headers = await this.http.createAuthHeaders(input.context, `commit SolidFS object: ${resourceUrl}`);
50
+ if (input.change.contentType) {
51
+ headers.set('Content-Type', input.change.contentType);
52
+ }
53
+ if (input.change.sourceVersion) {
54
+ headers.set('If-Match', input.change.sourceVersion);
55
+ }
56
+ const response = await this.http.request(resourceUrl, {
57
+ method: 'PUT',
58
+ headers,
59
+ body: (0, node_fs_1.createReadStream)(input.change.sourcePath),
60
+ duplex: 'half',
61
+ });
62
+ if (response.status === 409 || response.status === 412) {
63
+ throw new types_1.SolidFsConflictError([{
64
+ path: input.change.path,
65
+ sourcePath: input.change.sourcePath,
66
+ expectedVersion: input.change.sourceVersion,
67
+ actualVersion: this.responseVersion(response),
68
+ message: `Object authority changed before SolidFS commit: ${resourceUrl}`,
69
+ }]);
70
+ }
71
+ if (!response.ok) {
72
+ throw new Error(`SolidFS object commit failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);
73
+ }
74
+ return {
75
+ sourceVersion: this.responseVersion(response),
76
+ };
77
+ }
78
+ async delete(input) {
79
+ const resourceUrl = this.resolveChangeResourceUrl(input);
80
+ const headers = await this.http.createAuthHeaders(input.context, `delete SolidFS object: ${resourceUrl}`);
81
+ if (input.change.sourceVersion) {
82
+ headers.set('If-Match', input.change.sourceVersion);
83
+ }
84
+ const response = await this.http.request(resourceUrl, {
85
+ method: 'DELETE',
86
+ headers,
87
+ });
88
+ if (response.status === 409 || response.status === 412) {
89
+ throw new types_1.SolidFsConflictError([{
90
+ path: input.change.path,
91
+ sourcePath: input.change.sourcePath,
92
+ expectedVersion: input.change.sourceVersion,
93
+ actualVersion: this.responseVersion(response),
94
+ message: `Object authority changed before SolidFS delete: ${resourceUrl}`,
95
+ }]);
96
+ }
97
+ if (!response.ok && response.status !== 404) {
98
+ throw new Error(`SolidFS object delete failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);
99
+ }
100
+ }
101
+ resolveResourceUrl(relativePath, workspace) {
102
+ const resourceUrl = (0, PodSolidFsHttpClient_1.resolvePodWorkspaceResourceUrl)(relativePath, workspace);
103
+ if (!resourceUrl) {
104
+ throw new Error(`Cannot resolve SolidFS Pod resource URL for ${relativePath} in ${workspace.workspace}`);
105
+ }
106
+ return resourceUrl;
107
+ }
108
+ resolveChangeResourceUrl(input) {
109
+ if (input.change.resource) {
110
+ try {
111
+ const url = new URL(input.change.resource);
112
+ if (url.protocol === 'http:' || url.protocol === 'https:') {
113
+ return url.href;
114
+ }
115
+ }
116
+ catch {
117
+ // Fall through to workspace-relative resolution.
118
+ }
119
+ }
120
+ return this.resolveResourceUrl(input.change.path, input.workspace);
121
+ }
122
+ responseVersion(response) {
123
+ return response.headers.get('etag') ?? response.headers.get('last-modified') ?? undefined;
124
+ }
125
+ }
126
+ exports.PodSolidFsHydrator = PodSolidFsHydrator;
127
+ //# sourceMappingURL=PodSolidFsHydrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PodSolidFsHydrator.js","sourceRoot":"","sources":["../../src/solidfs/PodSolidFsHydrator.ts"],"names":[],"mappings":"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","sourcesContent":["import { createReadStream, createWriteStream } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { pipeline } from 'node:stream/promises';\n\nimport { SolidFsConflictError, SolidFsNotFoundError, type SolidFsCommitHydratedInput, type SolidFsHydrateInput, type SolidFsHydrator } from './types';\nimport { PodSolidFsHttpClient, resolvePodWorkspaceResourceUrl } from './PodSolidFsHttpClient';\n\nexport interface PodSolidFsHydratorOptions {\n fetch?: typeof fetch;\n tokenEndpoint?: string;\n}\n\n/**\n * Hydrates object-backed Pod resources through the normal Pod HTTP boundary.\n *\n * The API runtime should not reach into CSS' storage container. GET/PUT/DELETE\n * through CSS keeps authorization, object backends, and MixData/RDF indexing in\n * one protocol path.\n */\nexport class PodSolidFsHydrator implements SolidFsHydrator {\n private readonly http: PodSolidFsHttpClient;\n\n public constructor(options: PodSolidFsHydratorOptions = {}) {\n this.http = new PodSolidFsHttpClient(options);\n }\n\n public async hydrate(input: SolidFsHydrateInput): Promise<{ contentType?: string; sourceVersion?: string }> {\n const resourceUrl = this.resolveResourceUrl(input.path, input.workspace);\n const headers = await this.http.createAuthHeaders(input.context, `hydrate SolidFS object: ${resourceUrl}`);\n const response = await this.http.request(resourceUrl, {\n method: 'GET',\n headers,\n });\n\n if (response.status === 404) {\n throw new SolidFsNotFoundError(`SolidFS object not found: ${resourceUrl}`);\n }\n if (!response.ok) {\n throw new Error(`SolidFS object hydrate failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);\n }\n if (!response.body) {\n throw new Error(`SolidFS object hydrate failed for ${resourceUrl}: empty response body`);\n }\n\n await mkdir(path.dirname(input.targetPath), { recursive: true });\n await pipeline(response.body as any, createWriteStream(input.targetPath));\n\n return {\n contentType: response.headers.get('content-type') ?? undefined,\n sourceVersion: this.responseVersion(response),\n };\n }\n\n public async commit(input: SolidFsCommitHydratedInput): Promise<{ sourceVersion?: string }> {\n const resourceUrl = this.resolveChangeResourceUrl(input);\n const headers = await this.http.createAuthHeaders(input.context, `commit SolidFS object: ${resourceUrl}`);\n if (input.change.contentType) {\n headers.set('Content-Type', input.change.contentType);\n }\n if (input.change.sourceVersion) {\n headers.set('If-Match', input.change.sourceVersion);\n }\n\n const response = await this.http.request(resourceUrl, {\n method: 'PUT',\n headers,\n body: createReadStream(input.change.sourcePath) as any,\n duplex: 'half' as any,\n } as RequestInit);\n\n if (response.status === 409 || response.status === 412) {\n throw new SolidFsConflictError([{\n path: input.change.path,\n sourcePath: input.change.sourcePath,\n expectedVersion: input.change.sourceVersion,\n actualVersion: this.responseVersion(response),\n message: `Object authority changed before SolidFS commit: ${resourceUrl}`,\n }]);\n }\n if (!response.ok) {\n throw new Error(`SolidFS object commit failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);\n }\n\n return {\n sourceVersion: this.responseVersion(response),\n };\n }\n\n public async delete(input: SolidFsCommitHydratedInput): Promise<void> {\n const resourceUrl = this.resolveChangeResourceUrl(input);\n const headers = await this.http.createAuthHeaders(input.context, `delete SolidFS object: ${resourceUrl}`);\n if (input.change.sourceVersion) {\n headers.set('If-Match', input.change.sourceVersion);\n }\n\n const response = await this.http.request(resourceUrl, {\n method: 'DELETE',\n headers,\n });\n\n if (response.status === 409 || response.status === 412) {\n throw new SolidFsConflictError([{\n path: input.change.path,\n sourcePath: input.change.sourcePath,\n expectedVersion: input.change.sourceVersion,\n actualVersion: this.responseVersion(response),\n message: `Object authority changed before SolidFS delete: ${resourceUrl}`,\n }]);\n }\n if (!response.ok && response.status !== 404) {\n throw new Error(`SolidFS object delete failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);\n }\n }\n\n private resolveResourceUrl(relativePath: string, workspace: SolidFsHydrateInput['workspace']): string {\n const resourceUrl = resolvePodWorkspaceResourceUrl(relativePath, workspace);\n if (!resourceUrl) {\n throw new Error(`Cannot resolve SolidFS Pod resource URL for ${relativePath} in ${workspace.workspace}`);\n }\n return resourceUrl;\n }\n\n private resolveChangeResourceUrl(input: SolidFsCommitHydratedInput): string {\n if (input.change.resource) {\n try {\n const url = new URL(input.change.resource);\n if (url.protocol === 'http:' || url.protocol === 'https:') {\n return url.href;\n }\n } catch {\n // Fall through to workspace-relative resolution.\n }\n }\n return this.resolveResourceUrl(input.change.path, input.workspace);\n }\n\n private responseVersion(response: Response): string | undefined {\n return response.headers.get('etag') ?? response.headers.get('last-modified') ?? undefined;\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import type { SolidFsChange, SolidFsManifest, SolidFsSyncer } from './types';
2
+ export interface PodSolidFsSyncerOptions {
3
+ fetch?: typeof fetch;
4
+ tokenEndpoint?: string;
5
+ }
6
+ /**
7
+ * Writes SolidFS RDF file changes back through the Pod HTTP surface.
8
+ *
9
+ * The CSS/MixDataAccessor path remains responsible for parsing RDF documents
10
+ * into the structured RDF index. This adapter only bridges runtime workspace
11
+ * edits back to the Pod resource URL with the caller's stored auth context.
12
+ */
13
+ export declare class PodSolidFsSyncer implements SolidFsSyncer {
14
+ private readonly http;
15
+ constructor(options?: PodSolidFsSyncerOptions);
16
+ shouldTrack(input: {
17
+ workspace: string;
18
+ }): boolean;
19
+ sync(change: SolidFsChange, workspace: SolidFsManifest, context?: unknown): Promise<void>;
20
+ }
21
+ export declare function resolvePodResourceUrl(change: SolidFsChange, workspace: SolidFsManifest): string | undefined;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PodSolidFsSyncer = void 0;
4
+ exports.resolvePodResourceUrl = resolvePodResourceUrl;
5
+ const node_fs_1 = require("node:fs");
6
+ const RdfContentTypes_1 = require("../storage/rdf/RdfContentTypes");
7
+ const PodSolidFsHttpClient_1 = require("./PodSolidFsHttpClient");
8
+ /**
9
+ * Writes SolidFS RDF file changes back through the Pod HTTP surface.
10
+ *
11
+ * The CSS/MixDataAccessor path remains responsible for parsing RDF documents
12
+ * into the structured RDF index. This adapter only bridges runtime workspace
13
+ * edits back to the Pod resource URL with the caller's stored auth context.
14
+ */
15
+ class PodSolidFsSyncer {
16
+ constructor(options = {}) {
17
+ this.http = new PodSolidFsHttpClient_1.PodSolidFsHttpClient(options);
18
+ }
19
+ shouldTrack(input) {
20
+ try {
21
+ const url = new URL(input.workspace);
22
+ return url.protocol === 'http:' || url.protocol === 'https:';
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ async sync(change, workspace, context) {
29
+ if (!isRdfChange(change)) {
30
+ return;
31
+ }
32
+ const resourceUrl = resolvePodResourceUrl(change, workspace);
33
+ if (!resourceUrl) {
34
+ return;
35
+ }
36
+ const headers = await this.http.createAuthHeaders(context, `sync SolidFS RDF change: ${resourceUrl}`);
37
+ if (change.type === 'deleted') {
38
+ const response = await this.http.request(resourceUrl, {
39
+ method: 'DELETE',
40
+ headers,
41
+ });
42
+ if (!response.ok && response.status !== 404) {
43
+ throw new Error(`SolidFS RDF delete sync failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);
44
+ }
45
+ return;
46
+ }
47
+ headers.set('Content-Type', change.contentType ?? 'text/turtle');
48
+ const response = await this.http.request(resourceUrl, {
49
+ method: 'PUT',
50
+ headers,
51
+ body: (0, node_fs_1.createReadStream)(change.sourcePath),
52
+ duplex: 'half',
53
+ });
54
+ if (!response.ok) {
55
+ throw new Error(`SolidFS RDF write sync failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);
56
+ }
57
+ }
58
+ }
59
+ exports.PodSolidFsSyncer = PodSolidFsSyncer;
60
+ function resolvePodResourceUrl(change, workspace) {
61
+ if (change.resource) {
62
+ try {
63
+ const url = new URL(change.resource);
64
+ if (url.protocol === 'http:' || url.protocol === 'https:') {
65
+ return url.href;
66
+ }
67
+ return undefined;
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ }
73
+ return (0, PodSolidFsHttpClient_1.resolvePodWorkspaceResourceUrl)(change.path, workspace);
74
+ }
75
+ function isRdfChange(change) {
76
+ return (0, RdfContentTypes_1.isRdfDocument)(change.contentType, change.path);
77
+ }
78
+ //# sourceMappingURL=PodSolidFsSyncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PodSolidFsSyncer.js","sourceRoot":"","sources":["../../src/solidfs/PodSolidFsSyncer.ts"],"names":[],"mappings":"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","sourcesContent":["import { createReadStream } from 'node:fs';\n\nimport type { SolidFsChange, SolidFsManifest, SolidFsSyncer } from './types';\nimport { isRdfDocument } from '../storage/rdf/RdfContentTypes';\nimport { PodSolidFsHttpClient, resolvePodWorkspaceResourceUrl } from './PodSolidFsHttpClient';\n\nexport interface PodSolidFsSyncerOptions {\n fetch?: typeof fetch;\n tokenEndpoint?: string;\n}\n\n/**\n * Writes SolidFS RDF file changes back through the Pod HTTP surface.\n *\n * The CSS/MixDataAccessor path remains responsible for parsing RDF documents\n * into the structured RDF index. This adapter only bridges runtime workspace\n * edits back to the Pod resource URL with the caller's stored auth context.\n */\nexport class PodSolidFsSyncer implements SolidFsSyncer {\n private readonly http: PodSolidFsHttpClient;\n\n public constructor(options: PodSolidFsSyncerOptions = {}) {\n this.http = new PodSolidFsHttpClient(options);\n }\n\n public shouldTrack(input: { workspace: string }): boolean {\n try {\n const url = new URL(input.workspace);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n }\n\n public async sync(change: SolidFsChange, workspace: SolidFsManifest, context?: unknown): Promise<void> {\n if (!isRdfChange(change)) {\n return;\n }\n\n const resourceUrl = resolvePodResourceUrl(change, workspace);\n if (!resourceUrl) {\n return;\n }\n\n const headers = await this.http.createAuthHeaders(context, `sync SolidFS RDF change: ${resourceUrl}`);\n if (change.type === 'deleted') {\n const response = await this.http.request(resourceUrl, {\n method: 'DELETE',\n headers,\n });\n if (!response.ok && response.status !== 404) {\n throw new Error(`SolidFS RDF delete sync failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);\n }\n return;\n }\n\n headers.set('Content-Type', change.contentType ?? 'text/turtle');\n const response = await this.http.request(resourceUrl, {\n method: 'PUT',\n headers,\n body: createReadStream(change.sourcePath) as any,\n duplex: 'half' as any,\n } as RequestInit);\n if (!response.ok) {\n throw new Error(`SolidFS RDF write sync failed for ${resourceUrl}: ${response.status} ${await response.text().catch(() => '')}`);\n }\n }\n}\n\nexport function resolvePodResourceUrl(change: SolidFsChange, workspace: SolidFsManifest): string | undefined {\n if (change.resource) {\n try {\n const url = new URL(change.resource);\n if (url.protocol === 'http:' || url.protocol === 'https:') {\n return url.href;\n }\n return undefined;\n } catch {\n return undefined;\n }\n }\n return resolvePodWorkspaceResourceUrl(change.path, workspace);\n}\n\nfunction isRdfChange(change: SolidFsChange): boolean {\n return isRdfDocument(change.contentType, change.path);\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import { type ResourceIdentifier } from '@solid/community-server';
2
+ import type { LocalRdfIndexAccessor } from '../storage/accessors/MixDataAccessor';
3
+ import type { RdfTextIndex } from '../storage/rdf';
4
+ import type { SolidFsChange, SolidFsManifest, SolidFsSyncer } from './types';
5
+ export interface RdfIndexSolidFsSyncerOptions {
6
+ index: LocalRdfIndexAccessor;
7
+ textIndex?: RdfTextIndex;
8
+ resolveIdentifier?: (change: SolidFsChange, workspace: SolidFsManifest) => ResourceIdentifier | undefined;
9
+ }
10
+ /**
11
+ * Refreshes the structured RDF index for standard RDF documents changed
12
+ * through a SolidFS materialized workspace.
13
+ */
14
+ export declare class RdfIndexSolidFsSyncer implements SolidFsSyncer {
15
+ private readonly index;
16
+ private readonly textIndex?;
17
+ private readonly resolveIdentifier;
18
+ constructor(options: RdfIndexSolidFsSyncerOptions);
19
+ shouldTrackPath(relativePath: string): boolean;
20
+ sync(change: SolidFsChange, workspace: SolidFsManifest): Promise<void>;
21
+ }
22
+ export declare function defaultResolveIdentifier(change: SolidFsChange, workspace: SolidFsManifest): ResourceIdentifier | undefined;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RdfIndexSolidFsSyncer = void 0;
7
+ exports.defaultResolveIdentifier = defaultResolveIdentifier;
8
+ const node_fs_1 = require("node:fs");
9
+ const promises_1 = require("node:fs/promises");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const community_server_1 = require("@solid/community-server");
12
+ const RdfContentTypes_1 = require("../storage/rdf/RdfContentTypes");
13
+ /**
14
+ * Refreshes the structured RDF index for standard RDF documents changed
15
+ * through a SolidFS materialized workspace.
16
+ */
17
+ class RdfIndexSolidFsSyncer {
18
+ constructor(options) {
19
+ this.index = options.index;
20
+ this.textIndex = options.textIndex;
21
+ this.resolveIdentifier = options.resolveIdentifier ?? defaultResolveIdentifier;
22
+ }
23
+ shouldTrackPath(relativePath) {
24
+ return isRdfPath(relativePath) || (this.textIndex ? isTextPath(relativePath) : false);
25
+ }
26
+ async sync(change, workspace) {
27
+ if (!isTrackedChange(change)) {
28
+ return;
29
+ }
30
+ const identifier = this.resolveIdentifier(change, workspace);
31
+ if (!identifier && isRdfChange(change) && !this.textIndex) {
32
+ return;
33
+ }
34
+ if (change.type === 'deleted') {
35
+ if (identifier && isRdfChange(change)) {
36
+ await this.index.deleteLocalRdfIndex(identifier);
37
+ }
38
+ if (this.textIndex && isTextIndexableChange(change)) {
39
+ this.textIndex.deleteSource(change.resource ?? sourceFromWorkspace(change, workspace));
40
+ }
41
+ return;
42
+ }
43
+ if (identifier && isRdfChange(change)) {
44
+ const localPath = change.path.split(node_path_1.default.sep).join('/');
45
+ await this.index.syncLocalRdfDocument(identifier, (0, community_server_1.guardStream)((0, node_fs_1.createReadStream)(change.sourcePath)), change.contentType, {
46
+ source: change.resource ?? sourceFromWorkspace(change, workspace),
47
+ workspace: workspace.workspace,
48
+ localPath,
49
+ sourceVersion: change.sourceVersion,
50
+ });
51
+ }
52
+ if (this.textIndex && isTextIndexableChange(change)) {
53
+ const text = await (0, promises_1.readFile)(change.sourcePath, 'utf8');
54
+ this.textIndex.indexText({
55
+ source: change.resource ?? sourceFromWorkspace(change, workspace),
56
+ workspace: workspace.workspace,
57
+ localPath: change.path.split(node_path_1.default.sep).join('/'),
58
+ contentType: change.contentType,
59
+ sourceVersion: change.sourceVersion,
60
+ }, text);
61
+ }
62
+ }
63
+ }
64
+ exports.RdfIndexSolidFsSyncer = RdfIndexSolidFsSyncer;
65
+ function defaultResolveIdentifier(change, workspace) {
66
+ if (change.resource) {
67
+ try {
68
+ const resource = new URL(change.resource);
69
+ if (resource.protocol === 'http:' || resource.protocol === 'https:') {
70
+ return { path: resource.href };
71
+ }
72
+ }
73
+ catch {
74
+ return undefined;
75
+ }
76
+ return undefined;
77
+ }
78
+ try {
79
+ const base = new URL(workspace.workspace.endsWith('/') ? workspace.workspace : `${workspace.workspace}/`);
80
+ if (base.protocol !== 'http:' && base.protocol !== 'https:') {
81
+ return undefined;
82
+ }
83
+ const normalized = change.path.split(node_path_1.default.sep).join('/');
84
+ return { path: new URL(normalized, base).href };
85
+ }
86
+ catch {
87
+ return undefined;
88
+ }
89
+ }
90
+ function isRdfChange(change) {
91
+ return (0, RdfContentTypes_1.isRdfDocument)(change.contentType, change.path);
92
+ }
93
+ function isLineAddressableRdfChange(change) {
94
+ return (0, RdfContentTypes_1.isLineAddressableRdf)(change.contentType, change.path);
95
+ }
96
+ function isTextChange(change) {
97
+ return isTextContentType(change.contentType) || isTextPath(change.path);
98
+ }
99
+ function isTextIndexableChange(change) {
100
+ return isLineAddressableRdfChange(change) || isTextChange(change);
101
+ }
102
+ function isTrackedChange(change) {
103
+ return isRdfChange(change) || isTextChange(change);
104
+ }
105
+ function isRdfPath(filePath) {
106
+ return (0, RdfContentTypes_1.isRdfDocumentPath)(filePath);
107
+ }
108
+ function isTextPath(filePath) {
109
+ const lower = filePath.toLowerCase();
110
+ return lower.endsWith('.md')
111
+ || lower.endsWith('.markdown')
112
+ || lower.endsWith('.mdown')
113
+ || lower.endsWith('.txt')
114
+ || lower.endsWith('.log');
115
+ }
116
+ function isTextContentType(contentType) {
117
+ const normalized = (0, RdfContentTypes_1.normalizeContentType)(contentType);
118
+ return normalized === 'text/plain'
119
+ || normalized === 'text/markdown'
120
+ || normalized === 'text/x-markdown';
121
+ }
122
+ function sourceFromWorkspace(change, workspace) {
123
+ try {
124
+ const base = new URL(workspace.workspace.endsWith('/') ? workspace.workspace : `${workspace.workspace}/`);
125
+ return new URL(change.path.split(node_path_1.default.sep).join('/'), base).href;
126
+ }
127
+ catch {
128
+ return change.sourcePath;
129
+ }
130
+ }
131
+ //# sourceMappingURL=RdfIndexSolidFsSyncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RdfIndexSolidFsSyncer.js","sourceRoot":"","sources":["../../src/solidfs/RdfIndexSolidFsSyncer.ts"],"names":[],"mappings":";;;;;;AAwFA,4DA0BC;AAlHD,qCAA2C;AAC3C,+CAA4C;AAC5C,0DAA6B;AAC7B,8DAA+E;AAI/E,oEAKwC;AASxC;;;GAGG;AACH,MAAa,qBAAqB;IAKhC,YAAmB,OAAqC;QACtD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,wBAAwB,CAAC;IACjF,CAAC;IAEM,eAAe,CAAC,YAAoB;QACzC,OAAO,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxF,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,MAAqB,EAAE,SAA0B;QACjE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtC,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpD,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,IAAI,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;YACzF,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxD,MAAM,IAAI,CAAC,KAAK,CAAC,oBAAoB,CACnC,UAAU,EACV,IAAA,8BAAW,EAAC,IAAA,0BAAgB,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAChD,MAAM,CAAC,WAAW,EAClB;gBACE,MAAM,EAAE,MAAM,CAAC,QAAQ,IAAI,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC;gBACjE,SAAS,EAAE,SAAS,CAAC,SAAS;gBAC9B,SAAS;gBACT,aAAa,EAAE,MAAM,CAAC,aAAa;aACpC,CACF,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAQ,EAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACvD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;gBACvB,MAAM,EAAE,MAAM,CAAC,QAAQ,IAAI,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC;gBACjE,SAAS,EAAE,SAAS,CAAC,SAAS;gBAC9B,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAChD,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,aAAa,EAAE,MAAM,CAAC,aAAa;aACpC,EAAE,IAAI,CAAC,CAAC;QACX,CAAC;IACH,CAAC;CACF;AA7DD,sDA6DC;AAED,SAAgB,wBAAwB,CACtC,MAAqB,EACrB,SAA0B;IAE1B,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACpE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,SAAS,GAAG,CAAC,CAAC;QAC1G,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC5D,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzD,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAAqB;IACxC,OAAO,IAAA,+BAAa,EAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,0BAA0B,CAAC,MAAqB;IACvD,OAAO,IAAA,sCAAoB,EAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,YAAY,CAAC,MAAqB;IACzC,OAAO,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAqB;IAClD,OAAO,0BAA0B,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,eAAe,CAAC,MAAqB;IAC5C,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB;IACjC,OAAO,IAAA,mCAAiB,EAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,UAAU,CAAC,QAAgB;IAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;WACvB,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;WAC3B,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;WACxB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;WACtB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,iBAAiB,CAAC,WAA+B;IACxD,MAAM,UAAU,GAAG,IAAA,sCAAoB,EAAC,WAAW,CAAC,CAAC;IACrD,OAAO,UAAU,KAAK,YAAY;WAC7B,UAAU,KAAK,eAAe;WAC9B,UAAU,KAAK,iBAAiB,CAAC;AACxC,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAqB,EAAE,SAA0B;IAC5E,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,SAAS,GAAG,CAAC,CAAC;QAC1G,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,UAAU,CAAC;IAC3B,CAAC;AACH,CAAC","sourcesContent":["import { createReadStream } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { guardStream, type ResourceIdentifier } from '@solid/community-server';\n\nimport type { LocalRdfIndexAccessor } from '../storage/accessors/MixDataAccessor';\nimport type { RdfTextIndex } from '../storage/rdf';\nimport {\n isLineAddressableRdf,\n isRdfDocument,\n isRdfDocumentPath,\n normalizeContentType,\n} from '../storage/rdf/RdfContentTypes';\nimport type { SolidFsChange, SolidFsManifest, SolidFsSyncer } from './types';\n\nexport interface RdfIndexSolidFsSyncerOptions {\n index: LocalRdfIndexAccessor;\n textIndex?: RdfTextIndex;\n resolveIdentifier?: (change: SolidFsChange, workspace: SolidFsManifest) => ResourceIdentifier | undefined;\n}\n\n/**\n * Refreshes the structured RDF index for standard RDF documents changed\n * through a SolidFS materialized workspace.\n */\nexport class RdfIndexSolidFsSyncer implements SolidFsSyncer {\n private readonly index: LocalRdfIndexAccessor;\n private readonly textIndex?: RdfTextIndex;\n private readonly resolveIdentifier: NonNullable<RdfIndexSolidFsSyncerOptions['resolveIdentifier']>;\n\n public constructor(options: RdfIndexSolidFsSyncerOptions) {\n this.index = options.index;\n this.textIndex = options.textIndex;\n this.resolveIdentifier = options.resolveIdentifier ?? defaultResolveIdentifier;\n }\n\n public shouldTrackPath(relativePath: string): boolean {\n return isRdfPath(relativePath) || (this.textIndex ? isTextPath(relativePath) : false);\n }\n\n public async sync(change: SolidFsChange, workspace: SolidFsManifest): Promise<void> {\n if (!isTrackedChange(change)) {\n return;\n }\n\n const identifier = this.resolveIdentifier(change, workspace);\n if (!identifier && isRdfChange(change) && !this.textIndex) {\n return;\n }\n\n if (change.type === 'deleted') {\n if (identifier && isRdfChange(change)) {\n await this.index.deleteLocalRdfIndex(identifier);\n }\n if (this.textIndex && isTextIndexableChange(change)) {\n this.textIndex.deleteSource(change.resource ?? sourceFromWorkspace(change, workspace));\n }\n return;\n }\n\n if (identifier && isRdfChange(change)) {\n const localPath = change.path.split(path.sep).join('/');\n await this.index.syncLocalRdfDocument(\n identifier,\n guardStream(createReadStream(change.sourcePath)),\n change.contentType,\n {\n source: change.resource ?? sourceFromWorkspace(change, workspace),\n workspace: workspace.workspace,\n localPath,\n sourceVersion: change.sourceVersion,\n },\n );\n }\n\n if (this.textIndex && isTextIndexableChange(change)) {\n const text = await readFile(change.sourcePath, 'utf8');\n this.textIndex.indexText({\n source: change.resource ?? sourceFromWorkspace(change, workspace),\n workspace: workspace.workspace,\n localPath: change.path.split(path.sep).join('/'),\n contentType: change.contentType,\n sourceVersion: change.sourceVersion,\n }, text);\n }\n }\n}\n\nexport function defaultResolveIdentifier(\n change: SolidFsChange,\n workspace: SolidFsManifest,\n): ResourceIdentifier | undefined {\n if (change.resource) {\n try {\n const resource = new URL(change.resource);\n if (resource.protocol === 'http:' || resource.protocol === 'https:') {\n return { path: resource.href };\n }\n } catch {\n return undefined;\n }\n return undefined;\n }\n\n try {\n const base = new URL(workspace.workspace.endsWith('/') ? workspace.workspace : `${workspace.workspace}/`);\n if (base.protocol !== 'http:' && base.protocol !== 'https:') {\n return undefined;\n }\n const normalized = change.path.split(path.sep).join('/');\n return { path: new URL(normalized, base).href };\n } catch {\n return undefined;\n }\n}\n\nfunction isRdfChange(change: SolidFsChange): boolean {\n return isRdfDocument(change.contentType, change.path);\n}\n\nfunction isLineAddressableRdfChange(change: SolidFsChange): boolean {\n return isLineAddressableRdf(change.contentType, change.path);\n}\n\nfunction isTextChange(change: SolidFsChange): boolean {\n return isTextContentType(change.contentType) || isTextPath(change.path);\n}\n\nfunction isTextIndexableChange(change: SolidFsChange): boolean {\n return isLineAddressableRdfChange(change) || isTextChange(change);\n}\n\nfunction isTrackedChange(change: SolidFsChange): boolean {\n return isRdfChange(change) || isTextChange(change);\n}\n\nfunction isRdfPath(filePath: string): boolean {\n return isRdfDocumentPath(filePath);\n}\n\nfunction isTextPath(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n return lower.endsWith('.md')\n || lower.endsWith('.markdown')\n || lower.endsWith('.mdown')\n || lower.endsWith('.txt')\n || lower.endsWith('.log');\n}\n\nfunction isTextContentType(contentType: string | undefined): boolean {\n const normalized = normalizeContentType(contentType);\n return normalized === 'text/plain'\n || normalized === 'text/markdown'\n || normalized === 'text/x-markdown';\n}\n\nfunction sourceFromWorkspace(change: SolidFsChange, workspace: SolidFsManifest): string {\n try {\n const base = new URL(workspace.workspace.endsWith('/') ? workspace.workspace : `${workspace.workspace}/`);\n return new URL(change.path.split(path.sep).join('/'), base).href;\n } catch {\n return change.sourcePath;\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export * from './types';
2
+ export * from './LocalSolidFS';
3
+ export * from './PodSolidFsHttpClient';
4
+ export * from './PodSolidFsHydrator';
5
+ export * from './RdfIndexSolidFsSyncer';
6
+ export * from './PodSolidFsSyncer';
7
+ export * from './LocalFirstRdfRepresentationResolver';
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./LocalSolidFS"), exports);
19
+ __exportStar(require("./PodSolidFsHttpClient"), exports);
20
+ __exportStar(require("./PodSolidFsHydrator"), exports);
21
+ __exportStar(require("./RdfIndexSolidFsSyncer"), exports);
22
+ __exportStar(require("./PodSolidFsSyncer"), exports);
23
+ __exportStar(require("./LocalFirstRdfRepresentationResolver"), exports);
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/solidfs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,iDAA+B;AAC/B,yDAAuC;AACvC,uDAAqC;AACrC,0DAAwC;AACxC,qDAAmC;AACnC,wEAAsD","sourcesContent":["export * from './types';\nexport * from './LocalSolidFS';\nexport * from './PodSolidFsHttpClient';\nexport * from './PodSolidFsHydrator';\nexport * from './RdfIndexSolidFsSyncer';\nexport * from './PodSolidFsSyncer';\nexport * from './LocalFirstRdfRepresentationResolver';\n"]}