Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/boundaries.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ library could take their place there alone
| [interface.ts](../packages/solid/src/client/interface.ts) | the types the other modules take and give, `HttpError`, the sign-in client's interface and the grant's type; it imports no library |
| [rdf.ts](../packages/solid/src/client/rdf.ts) | the data model: datasets and their subjects, read and built, many subjects set or removed in one pass |
| [linearDataset.ts](../packages/solid/src/client/linearDataset.ts) | a document read into a dataset in one pass, where the library takes time in the square of its size, and the Turtle parser it and `parseQuads` read with, on `n3`, for `resources.ts` and `rdf.ts` alone |
| [readLimits.ts](../packages/solid/src/client/readLimits.ts) | the limits a read of a release, or of an instance's documents outside the user's own pod, takes in, the bounds every read keeps on a Turtle text's base and prefix declarations, on the long IRIs the parser resolves and on the length of each term, the fetch that holds a body to them, the tally that holds its triples to them, and the parts a parser is given a text in, to be stopped between them; it imports no library |
| [readLimits.ts](../packages/solid/src/client/readLimits.ts) | the limits a read of a release, or of an instance's documents outside the user's own pod, takes in, the bounds every read keeps on a Turtle text's base and prefix declarations, on the long IRIs the parser resolves, on how deep it nests and on the length of each term, the fetch that holds a body to them, the tally that holds its triples to them, and the parts a parser is given a text in, to be stopped between them; it imports no library |
| [linkHeader.ts](../packages/solid/src/client/linkHeader.ts) | the bound on the `Link` and `WAC-Allow` headers of a response, dropped past it before any parser reads them; it imports no library |
| [resources.ts](../packages/solid/src/client/resources.ts) | reading and writing pods, conditional reads and writes among them, and the Turtle and JSON-LD parsers |
| [sparqlUpdate.ts](../packages/solid/src/client/sparqlUpdate.ts) | the SPARQL Update bodies of the app's PATCH requests; it imports no library |
Expand Down
9 changes: 6 additions & 3 deletions docs/data-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -1657,9 +1657,12 @@ An import reads the file as the pod is read, with the same mappers:
So is one with an IRI longer than 512 characters, in a triple or a
prefix, that's relative or may hold a `.` or `..` segment, as
written or escaped. The parser removes those segments as it resolves
the IRI, in time growing with the square of its length. Its parse stops
there, as it stops at the first triple past the limits. A
declaration quoted in a card's text doesn't count. So is a file with
the IRI, in time growing with the square of its length. So is one
nested more than 64 levels deep in collections, blank nodes,
annotations or triple terms, which the parser holds memory for
without making a triple to count. Its parse stops there, as it stops
at the first triple past the limits. A declaration or a bracket
quoted in a card's text doesn't count. So is a file with
a term longer than 16,383 characters, as every document the app
reads is, and a JSON-LD file with a string or key that long, which
is refused before it's parsed. A
Expand Down
13 changes: 9 additions & 4 deletions docs/deck-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -1016,8 +1016,13 @@ flowchart LR
parser walks the whole base for each relative IRI, base and prefix it
resolves, and a declaration makes no triple to count. The search
reads the text as the parser does, past strings, IRIs and comments,
so a declaration quoted in a card's text doesn't count. With the
bases and prefixes bounded and the parse stopped at the first limit,
so a declaration or a bracket quoted in a card's text doesn't count.
It's refused, too, where it nests more than 64 levels deep in
collections, blank nodes, annotations or triple terms (`(`, `[`,
`{|`, `<<`). The parser holds memory for each level it's in, and
makes the triple that links a level to the one above only once the
level closes, so levels that never close make no triple to count.
With the bases and prefixes bounded and the parse stopped at the first limit,
the time to read or refuse a release grows with its size, not faster. Each case refuses
the release (`releaseTooLarge`), however the release is read. The
same limits apply to a creator's catalog read for the release's
Expand All @@ -1033,8 +1038,8 @@ flowchart LR
(`releaseUnreadable`), however it's read: the parser reads none, as
for a deck file, and stops at the first one. The library's
index, which comes with the site and grows with the library, and the
documents in the user's storages aren't limited in size. Their bases
and prefixes are, as those of every document the app reads into a
documents in the user's storages aren't limited in size. Their bases,
prefixes and nesting are, as those of every document the app reads into a
dataset, a folder's listing too; the document's
own address counts toward a base's length. An
instance's documents outside the user's storages, in an instance
Expand Down
2 changes: 1 addition & 1 deletion docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ Dependency inversion gives every layer a seam for its fakes:

| Layer | Seam | Technique |
|---|---|---|
| Domain | none needed | Pure functions; inputs (including `now: Date`) passed as parameters. Plain assertions. What runs over a whole deck or log is timed at two sizes in its own process's CPU time: eight times the input must take under four times as long as an eighth of it done eight times (a linear pass gives about one, work growing with the input about eight). The growth tests (`growth` in `src/testing/growth.ts`, `growthAsync` for work that awaits, `growthAfterSetup` for work that changes what it works on, set up afresh before each run and not timed) time `queryCards` over 5,000 cards, `lapseIndex`, `chainIndexOf` and `statisticsOf` over years of answers, `instanceGraphOf` over an instance's cards and answers and over a document thousands of folders deep, a course's outline (`courseOutlineFromRecords`) over its chapters and steps, the learner's progress in it (`courseProgress`) over a chapter's steps, the statistics of many courses (`getCourseStatistics`) over as many of their answers, the release check's course rules (`courseProblems`) and its rules on text written in Markdown (`markdownProblems`) over many cards, steps and chapters and their text formats and over one distractor that many cards name in many languages, a draft's outline (`draftOutline`) over the chapters and steps, a draft's cards with their wrong options, as the Studio's outline and its step, chapter and question pages show them (`draftCardOf`), over many cards, many wrong options of one card and one wrong option that many cards name in many languages, and the changes to a card's many wrong options (`distractorChanges`), the deck health's cards that say the same (`duplicateCardsOf`) over many cards alike, which of many decks with long release links are copies of a library of as many decks (`libraryCopyTest`) and which of the library's decks they copy (`copiedTest`), a JSON-LD copy (`jsonLdOf` in `solid`) over many values of one property, a document the guest's pod on the device stores and changes (`createLocalPod` in `solid`) over many lines past the bound on a term, alike but for their end, the search of a Turtle text for its base and prefix declarations and its long IRIs (`writeTurtle` in `solid`, and the refusal of a long IRI with dot segments in the client modules' contract tests), the shape check's report on a pod document and its check of a write (`createShaclShapeValidator` in `solid`, over an engine that answers at once) over a catalog's many links that aren't members and many dates it can't read, the SHACL engine's check of a graph and of each of its subjects (`createEngine` in `shacl`) over many subjects linking to a node with many types, the notes on a release's making (`makingNotesOf`) over many in one language, a draft's listing (`draftLibraryDeck`) and its release diff (`releaseDiff` and `simulateLearnerUpgrade`) over many sources, the draft as a release (`draftLibraryContent`) and a learner's upgrade to it over one wrong option that many cards name in many languages, a merge of drafts (`mergedDraft`) over many statements of one subject, the blank nodes a removal takes along (`withOnlyTheirBlankNodes` in `solid`) over many of one subject and many subjects naming one, many decks taken out of a catalog whose deck group lists many links, one of them no URL the app can write (`withoutDecks` in `solid`), the agent nodes of many authors that share a slug and a hash, alone and beside as many nodes other authors hold (`agentUrlsOf`), authors whose agent URLs are longer than any term, from a long subject or long names, at each place that keeps them (`TextMap`, `agentUrlsOf`, `deckAgents`, `withProvenance`, `deckReport`, `otherAuthorsOf`, a draft's listing, and `toDecks`, `deckSubjects` and `toLibraryDeckContent` in `solid`) and refused before anything is keyed by them (`deckToDraft`, and `withDeck`, a draft's entries, moved past the bound too, and a release assembled at a longer address, in `solid`), a catalog's decks (`toDecks` in `solid`) and a deck file's refusal (`readDeckFile`) over many decks and agents, a document's cards (`toCards` in `solid`) and a release's, read and refused (`toLibraryDeckContent` in `solid`), over many cards that name one distractor in many languages, a catalog written over many licenses it no longer states (`withCatalog` in `solid`), a deck's cards added from a release, or refused for a distractor many of them name, removed and brought to this app's format, one card's many distractors added and changed, a deck removed from a cards document another app wrote in, many decks of a catalog changed and removed at once, catalog entries and review states brought to this app's format, review states removed, a day's answers removed, many month summaries dropped from the digest and as many receipts noted in it at once as it holds, and many review states' snapshots dropped, decks removed and one deck's unreadable dates dropped by the instance check's repair, many registrations of an instance renamed and removed in a type index, and the storages found in a profile that names a large extended profile document, against a pod in memory (`importDeck`, `applyCardChanges`, `removeDeck`, `saveDecks`, `removeDecks`, `upgradeCards`, `upgradeDecks`, `upgradeReviewStates`, `applyReviewChanges`, `removeDay`, `updateDigest`, `applyRepairs`, `renameInstanceRegistrations`, `removeInstanceRegistrations` and `discoverStorages` in `solid`), the receipts a visit notes in the digest it keeps (`createDigestStore`) over a digest of as many, the repairs planned from a check of many subjects (`planRepair`), a subject's many values set or removed in one call (`setIriAll`, `setStringAll` and `removeLiteralAll`, in the client modules' contract tests), the Studio's graph layout and routes over a deck's cards, its card History tab and the learner's card page's history over many answers that name one of a card's many wrong options, and the Studio's cut of a label (`drawnLabel`), which must not grow with the label at all, over one millions of characters long. |
| Domain | none needed | Pure functions; inputs (including `now: Date`) passed as parameters. Plain assertions. What runs over a whole deck or log is timed at two sizes in its own process's CPU time: eight times the input must take under four times as long as an eighth of it done eight times (a linear pass gives about one, work growing with the input about eight). The growth tests (`growth` in `src/testing/growth.ts`, `growthAsync` for work that awaits, `growthAfterSetup` for work that changes what it works on, set up afresh before each run and not timed) time `queryCards` over 5,000 cards, `lapseIndex`, `chainIndexOf` and `statisticsOf` over years of answers, `instanceGraphOf` over an instance's cards and answers and over a document thousands of folders deep, a course's outline (`courseOutlineFromRecords`) over its chapters and steps, the learner's progress in it (`courseProgress`) over a chapter's steps, the statistics of many courses (`getCourseStatistics`) over as many of their answers, the release check's course rules (`courseProblems`) and its rules on text written in Markdown (`markdownProblems`) over many cards, steps and chapters and their text formats and over one distractor that many cards name in many languages, a draft's outline (`draftOutline`) over the chapters and steps, a draft's cards with their wrong options, as the Studio's outline and its step, chapter and question pages show them (`draftCardOf`), over many cards, many wrong options of one card and one wrong option that many cards name in many languages, and the changes to a card's many wrong options (`distractorChanges`), the deck health's cards that say the same (`duplicateCardsOf`) over many cards alike, which of many decks with long release links are copies of a library of as many decks (`libraryCopyTest`) and which of the library's decks they copy (`copiedTest`), a JSON-LD copy (`jsonLdOf` in `solid`) over many values of one property, a document the guest's pod on the device stores and changes (`createLocalPod` in `solid`) over many lines past the bound on a term, alike but for their end, the search of a Turtle text for its base and prefix declarations, its long IRIs and its nesting (`writeTurtle` in `solid`, and the refusal of a long IRI with dot segments in the client modules' contract tests), the shape check's report on a pod document and its check of a write (`createShaclShapeValidator` in `solid`, over an engine that answers at once) over a catalog's many links that aren't members and many dates it can't read, the SHACL engine's check of a graph and of each of its subjects (`createEngine` in `shacl`) over many subjects linking to a node with many types, the notes on a release's making (`makingNotesOf`) over many in one language, a draft's listing (`draftLibraryDeck`) and its release diff (`releaseDiff` and `simulateLearnerUpgrade`) over many sources, the draft as a release (`draftLibraryContent`) and a learner's upgrade to it over one wrong option that many cards name in many languages, a merge of drafts (`mergedDraft`) over many statements of one subject, the blank nodes a removal takes along (`withOnlyTheirBlankNodes` in `solid`) over many of one subject and many subjects naming one, many decks taken out of a catalog whose deck group lists many links, one of them no URL the app can write (`withoutDecks` in `solid`), the agent nodes of many authors that share a slug and a hash, alone and beside as many nodes other authors hold (`agentUrlsOf`), authors whose agent URLs are longer than any term, from a long subject or long names, at each place that keeps them (`TextMap`, `agentUrlsOf`, `deckAgents`, `withProvenance`, `deckReport`, `otherAuthorsOf`, a draft's listing, and `toDecks`, `deckSubjects` and `toLibraryDeckContent` in `solid`) and refused before anything is keyed by them (`deckToDraft`, and `withDeck`, a draft's entries, moved past the bound too, and a release assembled at a longer address, in `solid`), a catalog's decks (`toDecks` in `solid`) and a deck file's refusal (`readDeckFile`) over many decks and agents, a document's cards (`toCards` in `solid`) and a release's, read and refused (`toLibraryDeckContent` in `solid`), over many cards that name one distractor in many languages, a catalog written over many licenses it no longer states (`withCatalog` in `solid`), a deck's cards added from a release, or refused for a distractor many of them name, removed and brought to this app's format, one card's many distractors added and changed, a deck removed from a cards document another app wrote in, many decks of a catalog changed and removed at once, catalog entries and review states brought to this app's format, review states removed, a day's answers removed, many month summaries dropped from the digest and as many receipts noted in it at once as it holds, and many review states' snapshots dropped, decks removed and one deck's unreadable dates dropped by the instance check's repair, many registrations of an instance renamed and removed in a type index, and the storages found in a profile that names a large extended profile document, against a pod in memory (`importDeck`, `applyCardChanges`, `removeDeck`, `saveDecks`, `removeDecks`, `upgradeCards`, `upgradeDecks`, `upgradeReviewStates`, `applyReviewChanges`, `removeDay`, `updateDigest`, `applyRepairs`, `renameInstanceRegistrations`, `removeInstanceRegistrations` and `discoverStorages` in `solid`), the receipts a visit notes in the digest it keeps (`createDigestStore`) over a digest of as many, the repairs planned from a check of many subjects (`planRepair`), a subject's many values set or removed in one call (`setIriAll`, `setStringAll` and `removeLiteralAll`, in the client modules' contract tests), the Studio's graph layout and routes over a deck's cards, its card History tab and the learner's card page's history over many answers that name one of a card's many wrong options, and the Studio's cut of a label (`drawnLabel`), which must not grow with the label at all, over one millions of characters long. |
| Application | ports | Fake ports are injected (`vi.fn` per method): the fixtures and fake ports in [fakePorts.ts](../packages/application/src/testing/fakePorts.ts), and `NO_PORTS` ([noPorts.ts](../packages/application/src/testing/noPorts.ts)), which other packages' tests spread too, for the ports a test doesn't use. Each slice is tested in its own `<feature>.test.ts`, the stores the slices share in theirs. No module mocking. |
| UI | `UseCases` prop | Screens render with a fake `UseCases`: `makeUseCasesFake` ([useCasesFake.ts](../packages/ui/src/test/useCasesFake.ts)) makes every slice's fake ([test/fakes/](../packages/ui/src/test/fakes/)) in one object, each calling the others through it. A screen that takes a slice (the trial's) can be given that slice's fake alone. Assertions use testing-library queries. Query-dependent components get a fresh `QueryClient` (retries off). |
| Infrastructure mappers | none needed | Pure `Dataset`/`Subject` → domain functions, fed in-memory datasets built with `datasetFrom`/`buildThing` ([datasets.ts](../packages/solid/src/testing/datasets.ts)). |
Expand Down
8 changes: 4 additions & 4 deletions packages/solid-memo-client/src/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ function resourceOf(response: Response): Resource {
* drops what was kept and rejects once, with a ReadLimitError (the
* triples counted into `spent` too, when the read shares its limits
* with others: limitedFetch), as
* `refuse` does for a text whose declarations or IRIs are past what a
* `refuse` does for a text whose declarations, IRIs or nesting are past what a
* read takes in, with limits or with none (writeTurtle); nothing
* more is kept, and `refused` says to stop the parser. A quad that
* names an IRI kept for subjects not saved yet is tallied and not kept
Expand Down Expand Up @@ -202,8 +202,8 @@ function collector(

/**
* The quads of a Turtle text, its relative IRIs resolved against
* `baseIRI`, under `limits` (collector), refused at a base, prefix or
* IRI past what any read takes in (writeTurtle). The text is written to
* `baseIRI`, under `limits` (collector), refused at a base, prefix,
* IRI or level of nesting past what any read takes in (writeTurtle). The text is written to
* the parser in parts, so that it reads no further than the part it is
* in. A text with an RDF 1.2 triple term does not parse: n3 is told to
* read none (TURTLE_OPTIONS), and the parse fails at the first triple
Expand Down Expand Up @@ -694,7 +694,7 @@ const MEDIA_TYPES = { turtle: TURTLE, jsonld: "application/ld+json" } as const;
* against `baseUrl`, parsed as a pod's documents are: in every graph the
* text names. Rejects with the parser's error on a text that does not
* parse, and with a ReadLimitError at the first quad past `limits`, or
* on a Turtle text at its first base, prefix or IRI past what a read
* on a Turtle text at its first base, prefix, IRI or level of nesting past what a read
* takes in, with limits or with none (writeTurtle).
*/
export async function parseQuads(
Expand Down
Loading
Loading