Repository navigation
feat(solid-memo-client): add a Solid client of the app's own - #332
Merged
Merged
Conversation
client/sparqlUpdate.ts imported changesOf and localNameOf from the Inrupt RDF module, so a second implementation of the client modules could not use it without reaching that library. patchBody and tripleLine now take the changes and the local-name reading they spell, and the resource module and datasets.ts pass the RDF module's own; the bodies are the same. The resource contract works out the bodies it expects from the client it is given. Refs: #331
The client modules' seams and contract were meant to let another implementation take Inrupt's place. @solid-memo/solid-memo-client is one, using no Inrupt package: the RDF data model and resources on n3 and jsonld-streaming-parser with plain fetch, Solid-OIDC sign-in on oauth4webapi with a DPoP key WebCrypto keeps non-extractable in IndexedDB, the public-read grant on WAC and ACP, and shacl's Turtle reader. It passes the same contract suites, at 100% coverage. Inrupt's clients stay the default. SOLID_CLIENT=solid-memo-client makes the build and the tests take the new one: a Vite plugin (scripts/solidClient.ts) resolves each client module to the module of the same name in the new package, so no caller changes, and any other value fails. Turbo hashes the choice and the package's sources. No package imports the new one and it imports no Inrupt package, which check:boundaries enforces; check:exports counts its exports as used where the module they replace is. Refs: #331
The second client is only worth keeping if it keeps working. Two jobs run with SOLID_CLIENT=solid-memo-client: the solid, shacl, composition and web packages' tests, and the pod tests on each blocking server. They are advisory, so a failure shows on a pull request without holding up a merge; the package's own tests, in check, block as every package's do. Refs: #331
A page of its own says what the second client is built on, how it keeps a session, how it grants public read, where it differs from Inrupt's and how it is tested; the vendor, boundary, sign-in, privacy, standards and testing pages say where it fits. Closes: #331
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Solid Memo reads and writes pods, and signs in, through Inrupt's libraries alone. #323 put them behind modules of the app's own, but with no second implementation, nothing showed that those seams hold. This adds one,
@solid-memo/solid-memo-client(packages/solid-memo-client), which uses no Inrupt package:n3andjsonld-streaming-parser, with plainfetch. It sends the same requests and PATCH bodies as Inrupt's client.oauth4webapi, with PKCE and DPoP-bound tokens from a WebCrypto key that can't be extracted. The key, the refresh token and the provider's registration are kept in IndexedDB, and access tokens in memory only. Refresh and logout take a Web Lock, so tabs don't race.acl:default, and keeps the owner's control.n3.Inrupt's clients stay the default.
SOLID_CLIENT=solid-memo-clientmakes a build or a test run use the new client through a Vite plugin (scripts/solidClient.ts), which resolves each client module to its namesake in the new package, so no caller changes. Leaving it unset, or settinginrupt, keeps Inrupt; any other value fails when a config loads. Turbo hashes the choice, so a cached result never stands for the other client.The commits:
refactor(solid):client/sparqlUpdate.tstakes the changes it writes instead of importing them from the Inrupt RDF module. The PATCH bodies are unchanged.feat(solid-memo-client): the package, at 100% coverage, passing the same contract suites; the switch; boundary rules (no Inrupt import in it, and no package imports it); andcheck:exportsandcheck:dependenciestaught about it.ci: two advisory jobs with the switch on:solid-memo-client (unit)runs the solid, shacl, composition and web tests, andsolid-memo-client (<server>)runs the pod tests on each blocking server. They show a failure without holding up a merge.docs: docs/solid-memo-client.md covers what it is built on, how it keeps a session, how it grants access, where it differs from Inrupt's client, and how it is tested. The vendor, boundary, sign-in, privacy, standards, testing and architecture pages say where it fits.With the switch on, I also ran:
After merging: keep the two
solid-memo-clientjobs out of the required checks in the branch protection rules. They are advisory, and they add six jobs to each run.Closes: #331
Checklist
Refs:, notCloses:. Leave this unchecked otherwise.npm run checkpasses (lint, Markdown and spelling included),npm run lint:reusetoo if a file was added, andnpm run crosschecktoo ifns/ordecks/changed. (npm run checkpasses on each commit;lint:reuseandlint:workflowspass too; crosscheck n/a:ns/anddecks/are unchanged.)docs/is listed in docs/docs.ttl.packages/ui/src/i18n/). (n/a: no message changed)ns/was agreed in an issue first; no publishedns/shapes/*/vN.ttlordecks/*/vN.ttlwas edited; generated files were regenerated, not edited. (n/a:ns/anddecks/are unchanged)!and aBREAKING CHANGE:footer).npm run check:breakingsees a line ofapi/that goes, but not a feature removed, nor a reader that reads less than before.npm run lint:reuse), or a new deck its line inREUSE.toml; third-party content is credited.npm run dev) and tried the change, and considered the user journeys.type(scope): subject,!and aBREAKING CHANGE:footer if it breaks something), with an imperative subject and a body that explains why (CONTRIBUTING.md).