@lernapps/app-templates 0.0.0-stage → 0.1.0
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.
- package/LICENSE +22 -0
- package/README.md +195 -2
- package/dist/appname-Bh23cUuz.mjs +12 -0
- package/dist/assessment-By2GGTJC.mjs +1696 -0
- package/dist/block-BK_ohsH1.mjs +82 -0
- package/dist/blocks-BmRrD7UY.mjs +149 -0
- package/dist/blocks.mjs +4 -0
- package/dist/check-BkEl-m-F.mjs +254 -0
- package/dist/content-cYBPYg_J.mjs +140 -0
- package/dist/contract-PONpxJtd.mjs +52 -0
- package/dist/e2e-BiMI-pCL.mjs +89 -0
- package/dist/engine-BqF2Vffn.mjs +136 -0
- package/dist/explainer-e2e.mjs +1297 -0
- package/dist/explainer-islands.mjs +197 -0
- package/dist/explainer-plugin.mjs +2131 -0
- package/dist/explainer.mjs +1246 -0
- package/dist/html-mffkHGHh.mjs +89 -0
- package/dist/image-CspJVfyQ.mjs +21 -0
- package/dist/interactive-e2e.mjs +140 -0
- package/dist/interactive-plugin.mjs +242 -0
- package/dist/interactive.mjs +75 -0
- package/dist/load-C-0hUaSC.mjs +16947 -0
- package/dist/needs-BzEahJ6X.mjs +97 -0
- package/dist/pages-9RaaomoO.mjs +81 -0
- package/dist/questions-e2e.mjs +1 -0
- package/dist/questions-engine.mjs +3 -0
- package/dist/questions.mjs +6 -0
- package/dist/quiz-BKc8JYtC.mjs +70 -0
- package/dist/quiz-e2e.mjs +174 -0
- package/dist/quiz-plugin.mjs +266 -0
- package/dist/quiz.mjs +246 -0
- package/dist/render-BJey0bwl.mjs +540 -0
- package/dist/render-BL6fV_NI.mjs +507 -0
- package/dist/render-DpRO_RKm.mjs +146 -0
- package/dist/result-_eQcamoz.mjs +180 -0
- package/dist/tasks-DADUYy52.mjs +74 -0
- package/dist/validate-COaZso7u.mjs +1072 -0
- package/dist/validate-CxtdeQ5S.mjs +146 -0
- package/dist/vue-DO1m6q1R.mjs +40 -0
- package/dist/vue-code-BkJjW_I_.mjs +320 -0
- package/docs/arc42/01-introduction-and-goals.arc42.md +82 -0
- package/docs/arc42/02-constraints.arc42.md +228 -0
- package/docs/arc42/03-system-context.arc42.md +118 -0
- package/docs/arc42/04-solution-strategy.arc42.md +47 -0
- package/docs/arc42/05-building-blocks.arc42.md +307 -0
- package/docs/arc42/06-runtime-view.arc42.md +98 -0
- package/docs/arc42/07-deployment-view.arc42.md +160 -0
- package/docs/arc42/08-concepts.arc42.md +123 -0
- package/docs/arc42/09-decisions.arc42.md +246 -0
- package/docs/arc42/10-quality-requirements.arc42.md +155 -0
- package/docs/arc42/11-risks.arc42.md +113 -0
- package/docs/arc42/12-glossary.arc42.md +162 -0
- package/docs/arc42/architecture-evidence.md +395 -0
- package/explainer/.arc42ignore +3 -0
- package/explainer/README.md +54 -0
- package/explainer/_gitignore +5 -0
- package/explainer/docs/arc42/03-explainer-system-context.arc42.md +35 -0
- package/explainer/docs/arc42/05-explainer-building-blocks.arc42.md +659 -0
- package/explainer/docs/arc42/06-explainer-runtime-view.arc42.md +105 -0
- package/explainer/docs/arc42/07-explainer-deployment-view.arc42.md +34 -0
- package/explainer/docs/arc42/08-explainer-concepts.arc42.md +17 -0
- package/explainer/docs/arc42/09-explainer-decisions.arc42.md +443 -0
- package/explainer/docs/arc42/10-explainer-quality-requirements.arc42.md +54 -0
- package/explainer/docs/arc42/11-explainer-risks.arc42.md +17 -0
- package/explainer/docs/arc42/12-explainer-glossary.arc42.md +185 -0
- package/explainer/e2e/explainer.e2e.ts +3 -0
- package/explainer/index.html +11 -0
- package/explainer/package.json +18 -0
- package/explainer/playwright.config.ts +1 -0
- package/explainer/src/app.yaml +20 -0
- package/explainer/src/components/ProzentFeld.test.ts +30 -0
- package/explainer/src/components/ProzentFeld.ts +121 -0
- package/explainer/src/components/ProzentFeld.vue +84 -0
- package/explainer/src/images/hunderterfeld-klammern.svg +105 -0
- package/explainer/src/main.ts +4 -0
- package/explainer/src/prozent/chapter.yaml +18 -0
- package/explainer/src/prozent/grundwert.yaml +115 -0
- package/explainer/src/prozent/prozentsatz.yaml +99 -0
- package/explainer/src/prozent/prozentwert.yaml +119 -0
- package/explainer/tsconfig.json +1 -0
- package/explainer/vite.config.ts +4 -0
- package/interactive/.arc42ignore +5 -0
- package/interactive/README.md +28 -0
- package/interactive/_gitignore +4 -0
- package/interactive/docs/arc42/05-interactive-building-blocks.arc42.md +518 -0
- package/interactive/docs/arc42/06-interactive-runtime-view.arc42.md +58 -0
- package/interactive/docs/arc42/07-interactive-deployment-view.arc42.md +35 -0
- package/interactive/docs/arc42/08-interactive-concepts.arc42.md +52 -0
- package/interactive/docs/arc42/09-interactive-decisions.arc42.md +130 -0
- package/interactive/docs/arc42/10-interactive-quality-requirements.arc42.md +45 -0
- package/interactive/docs/arc42/11-interactive-risks.arc42.md +20 -0
- package/interactive/docs/arc42/12-interactive-glossary.arc42.md +80 -0
- package/interactive/e2e/interactive.e2e.ts +3 -0
- package/interactive/index.html +11 -0
- package/interactive/package.json +18 -0
- package/interactive/playwright.config.ts +1 -0
- package/interactive/src/app.yaml +28 -0
- package/interactive/src/core/index.ts +101 -0
- package/interactive/src/data/lessons.json +4 -0
- package/interactive/src/env.d.ts +6 -0
- package/interactive/src/main.ts +6 -0
- package/interactive/src/messages/de.json +12 -0
- package/interactive/src/playthroughs/grundreihe.yaml +33 -0
- package/interactive/src/playthroughs/obere-reihe.yaml +14 -0
- package/interactive/src/ui/App.vue +85 -0
- package/interactive/tsconfig.json +1 -0
- package/interactive/vite.config.ts +4 -0
- package/package.json +144 -4
- package/quiz/README.md +31 -0
- package/quiz/_gitignore +5 -0
- package/quiz/docs/arc42/05-quiz-building-blocks.arc42.md +283 -0
- package/quiz/docs/arc42/06-quiz-runtime-view.arc42.md +21 -0
- package/quiz/docs/arc42/07-quiz-deployment-view.arc42.md +33 -0
- package/quiz/docs/arc42/09-quiz-decisions.arc42.md +36 -0
- package/quiz/docs/arc42/10-quiz-quality-requirements.arc42.md +53 -0
- package/quiz/docs/arc42/11-quiz-risks.arc42.md +19 -0
- package/quiz/docs/arc42/12-quiz-glossary.arc42.md +27 -0
- package/quiz/e2e/quiz.e2e.ts +3 -0
- package/quiz/index.html +11 -0
- package/quiz/package.json +18 -0
- package/quiz/playwright.config.ts +1 -0
- package/quiz/src/images/berge-ordnen.jpg +0 -0
- package/quiz/src/images/everest-hoehe.jpg +0 -0
- package/quiz/src/images/galapagos.jpg +0 -0
- package/quiz/src/images/grand-canyon.jpg +0 -0
- package/quiz/src/images/totes-meer.jpg +0 -0
- package/quiz/src/images/uluru.jpg +0 -0
- package/quiz/src/images/wasserfaelle-laender.jpg +0 -0
- package/quiz/src/main.ts +4 -0
- package/quiz/src/quiz.json +312 -0
- package/quiz/tsconfig.json +1 -0
- package/quiz/vite.config.ts +4 -0
- package/runtime/explainer/assessment-client.ts +478 -0
- package/runtime/explainer/assessment-page.ts +446 -0
- package/runtime/explainer/assessment.ts +393 -0
- package/runtime/explainer/check-page.ts +520 -0
- package/runtime/explainer/components/exercise.ts +409 -0
- package/runtime/explainer/components/props.ts +230 -0
- package/runtime/explainer/components/read.ts +428 -0
- package/runtime/explainer/content.ts +277 -0
- package/runtime/explainer/e2e.ts +1474 -0
- package/runtime/explainer/exercises.ts +324 -0
- package/runtime/explainer/explainer.css +1283 -0
- package/runtime/explainer/explainer.ts +838 -0
- package/runtime/explainer/explainer.v1.schema.json +1165 -0
- package/runtime/explainer/expression.ts +407 -0
- package/runtime/explainer/fraction.ts +107 -0
- package/runtime/explainer/generated/comparator.ts +31 -0
- package/runtime/explainer/generated/question.ts +165 -0
- package/runtime/explainer/generated/soundness.ts +280 -0
- package/runtime/explainer/generated/texts.ts +257 -0
- package/runtime/explainer/generated/types.ts +103 -0
- package/runtime/explainer/generated/values.ts +136 -0
- package/runtime/explainer/islands.ts +281 -0
- package/runtime/explainer/load.ts +457 -0
- package/runtime/explainer/messages/de.json +200 -0
- package/runtime/explainer/messages/en.json +200 -0
- package/runtime/explainer/messages.ts +13 -0
- package/runtime/explainer/needs.ts +122 -0
- package/runtime/explainer/open-task.ts +235 -0
- package/runtime/explainer/outline.ts +299 -0
- package/runtime/explainer/plugin.ts +488 -0
- package/runtime/explainer/position.ts +62 -0
- package/runtime/explainer/prompt.ts +75 -0
- package/runtime/explainer/render.ts +686 -0
- package/runtime/explainer/result.ts +238 -0
- package/runtime/explainer/routes.ts +119 -0
- package/runtime/explainer/schema.ts +140 -0
- package/runtime/explainer/scope.ts +87 -0
- package/runtime/explainer/stuck.ts +57 -0
- package/runtime/explainer/tasks.ts +109 -0
- package/runtime/explainer/tutor.ts +469 -0
- package/runtime/explainer/tutorpage.ts +669 -0
- package/runtime/explainer/video.ts +123 -0
- package/runtime/interactive/contract.ts +121 -0
- package/runtime/interactive/e2e.ts +190 -0
- package/runtime/interactive/interactive.css +82 -0
- package/runtime/interactive/interactive.ts +115 -0
- package/runtime/interactive/interactive.v1.schema.json +146 -0
- package/runtime/interactive/load.ts +188 -0
- package/runtime/interactive/messages/de.json +14 -0
- package/runtime/interactive/messages/en.json +14 -0
- package/runtime/interactive/messages.ts +11 -0
- package/runtime/interactive/playthrough.v1.schema.json +143 -0
- package/runtime/interactive/plugin.ts +266 -0
- package/runtime/interactive/render.ts +126 -0
- package/runtime/quiz/e2e.ts +233 -0
- package/runtime/quiz/engine.ts +242 -0
- package/runtime/quiz/messages/de.json +23 -0
- package/runtime/quiz/messages/en.json +23 -0
- package/runtime/quiz/plugin.ts +150 -0
- package/runtime/quiz/quiz.css +154 -0
- package/runtime/quiz/quiz.ts +56 -0
- package/runtime/quiz/quiz.v1.schema.json +72 -0
- package/runtime/quiz/render.ts +173 -0
- package/runtime/quiz/validate.ts +108 -0
- package/runtime/shared/appname.ts +16 -0
- package/runtime/shared/blocks/block.ts +162 -0
- package/runtime/shared/blocks/blocks.css +190 -0
- package/runtime/shared/blocks/blocks.v1.schema.json +432 -0
- package/runtime/shared/blocks/code.ts +26 -0
- package/runtime/shared/blocks/figures.ts +49 -0
- package/runtime/shared/blocks/image.ts +25 -0
- package/runtime/shared/blocks/index.ts +13 -0
- package/runtime/shared/blocks/messages/de.json +4 -0
- package/runtime/shared/blocks/messages/en.json +4 -0
- package/runtime/shared/blocks/render.ts +134 -0
- package/runtime/shared/blocks/validate.ts +165 -0
- package/runtime/shared/content.ts +197 -0
- package/runtime/shared/examples.ts +20 -0
- package/runtime/shared/html.ts +10 -0
- package/runtime/shared/languages.ts +94 -0
- package/runtime/shared/page.css +101 -0
- package/runtime/shared/pages.ts +114 -0
- package/runtime/shared/questions/e2e.ts +115 -0
- package/runtime/shared/questions/engine.ts +209 -0
- package/runtime/shared/questions/index.ts +39 -0
- package/runtime/shared/questions/messages/de.json +26 -0
- package/runtime/shared/questions/messages/en.json +26 -0
- package/runtime/shared/questions/question.ts +430 -0
- package/runtime/shared/questions/question.v1.schema.json +342 -0
- package/runtime/shared/questions/questions.css +192 -0
- package/runtime/shared/questions/render.ts +247 -0
- package/runtime/shared/questions/validate.ts +518 -0
- package/runtime/shared/schema.ts +44 -0
- package/runtime/shared/text/check.ts +68 -0
- package/runtime/shared/text/formula.ts +69 -0
- package/runtime/shared/text/markdown.ts +185 -0
- package/runtime/shared/text/text.v1.schema.json +34 -0
- package/runtime/shared/vue-code.ts +395 -0
- package/runtime/shared/vue.ts +38 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Building Blocks
|
|
2
|
+
|
|
3
|
+
The generic part has three roots that every app shares, whatever its archetype: the shared runtime of
|
|
4
|
+
`@lernapps/app-templates`, the tooling helpers of `@lernapps/tooling` and the skills the app commits. Each archetype's extension adds the rest of
|
|
5
|
+
level 1 (`quiz/docs/arc42/`, `explainer/docs/arc42/`, `interactive/docs/arc42/`): its runtime `bb-archetype-runtime`
|
|
6
|
+
with the parts `bb-build`, `bb-validation`, `bb-render`, `bb-shell`, `bb-e2e` and `bb-runtime-texts`, which every
|
|
7
|
+
extension defines under these ids, and the parts the creator writes, one of which provides `if-archetype-content`.
|
|
8
|
+
Parts that only some archetypes have (component rules, question types, tutor handoff, task numbers, exercise contract)
|
|
9
|
+
are in the extensions that use them. Not built and not in the frame now: a loading indicator (`dec-no-size-limit`) and
|
|
10
|
+
a settings dialog (`dec-no-settings`).
|
|
11
|
+
|
|
12
|
+
Paths are relative to the root of `lernapps/app-templates`. The parts in a template folder carry their path with the
|
|
13
|
+
folder as prefix (`interactive/src/core`); an app that gets this architecture as a copy has them without it
|
|
14
|
+
(`src/core`). An app's architecture is this part followed by its archetype's extension, chapter by chapter; so the
|
|
15
|
+
level-1 view of a whole app is in its extension.
|
|
16
|
+
|
|
17
|
+
## Level 1: the generic roots
|
|
18
|
+
|
|
19
|
+
```arc42
|
|
20
|
+
:::diagram
|
|
21
|
+
id: building-blocks-generic
|
|
22
|
+
view: building-block
|
|
23
|
+
notation: mermaid
|
|
24
|
+
:::
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```mermaid
|
|
28
|
+
flowchart TB
|
|
29
|
+
subgraph bb-runtime["Shared runtime (runtime/shared)"]
|
|
30
|
+
bb-blocks["Content blocks (runtime/shared/blocks)"]
|
|
31
|
+
bb-questions["Questions (runtime/shared/questions)"]
|
|
32
|
+
bb-component-rules["Component rules (runtime/shared/vue-code.ts)"]
|
|
33
|
+
end
|
|
34
|
+
bb-tooling["Tooling helpers (@lernapps/tooling)"]
|
|
35
|
+
bb-skills["Skills (.agents/skills)"]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Shared runtime
|
|
39
|
+
|
|
40
|
+
Built. The code the archetypes' runtimes share: the page trees, German at the root and every other language below
|
|
41
|
+
`/<language>/`, with alternates, a language switch of plain links and the 404 page, which leads every address the
|
|
42
|
+
app does not have to its start page (`pages.ts`); learner texts by language (`languages.ts`); the examples check,
|
|
43
|
+
which runs an exercise's accepted and rejected examples through the check the page uses, for the quiz and the
|
|
44
|
+
explainer (`examples.ts`); the content as YAML, with its problems placed at file, line and path, the errors of a schema
|
|
45
|
+
as problems and the checks of the texts (`content.ts`); restricted Markdown and formulas (`text/`); the checks of the
|
|
46
|
+
code of Vue components (`vue-code.ts`); HTML escaping (`html.ts`); the frame of every page, with its colours in the light and the dark scheme, its header with the language switch and its footer (`page.css`, `pages.ts`); the content blocks (`blocks/`); the questions, their six types with checker, schema, validation, rendering, engine, end-to-end
|
|
47
|
+
helpers and texts, which the quiz and the explainer's exercises both use (`questions/`); Vue at build for the archetypes with components (`vue.ts`); and the app's name, the prefix
|
|
48
|
+
of what it stores (`appname.ts`). The app never edits it.
|
|
49
|
+
|
|
50
|
+
```arc42
|
|
51
|
+
:::building-block
|
|
52
|
+
id: bb-runtime
|
|
53
|
+
title: Shared runtime
|
|
54
|
+
path: runtime/shared
|
|
55
|
+
technology: TypeScript
|
|
56
|
+
implements: concept-languages, concept-readable-without-js
|
|
57
|
+
:::
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Shared runtime modules
|
|
61
|
+
|
|
62
|
+
The archetype's runtime imports them at build and in its tests.
|
|
63
|
+
|
|
64
|
+
```arc42
|
|
65
|
+
:::interface
|
|
66
|
+
id: if-shared-runtime
|
|
67
|
+
title: Page trees, languages, examples check, Vue at build
|
|
68
|
+
provider: bb-runtime
|
|
69
|
+
protocol: TypeScript imports (runtime/shared)
|
|
70
|
+
path: runtime/shared
|
|
71
|
+
:::
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Content blocks
|
|
75
|
+
|
|
76
|
+
Built in the shared runtime, for every archetype that shows content with its questions or on its pages: prose, a
|
|
77
|
+
formula, a figure (drawn from data, or a bundled image of `src/images/`), a labelled figure, a table, a quotation and
|
|
78
|
+
program code, with the credit of an image or a quotation. Their types, their schema, their checks (what the schema
|
|
79
|
+
cannot say, every text complete in the declared languages), their rendering at build and their look; the quiz shows
|
|
80
|
+
them as the `material` of a question, the explainer as blocks of a page.
|
|
81
|
+
|
|
82
|
+
```arc42
|
|
83
|
+
:::building-block
|
|
84
|
+
id: bb-blocks
|
|
85
|
+
title: Content blocks
|
|
86
|
+
parent: bb-runtime
|
|
87
|
+
path: runtime/shared/blocks
|
|
88
|
+
technology: TypeScript
|
|
89
|
+
:::
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Content blocks interface
|
|
93
|
+
|
|
94
|
+
The validation and the rendering of an archetype with content blocks use their types, checks and renderer.
|
|
95
|
+
|
|
96
|
+
```arc42
|
|
97
|
+
:::interface
|
|
98
|
+
id: if-blocks
|
|
99
|
+
title: The content blocks (checkMaterial, renderMaterial, materialIn)
|
|
100
|
+
provider: bb-blocks
|
|
101
|
+
protocol: TypeScript imports (runtime/shared/blocks), @lernapps/app-templates/blocks
|
|
102
|
+
path: runtime/shared/blocks
|
|
103
|
+
:::
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Questions
|
|
107
|
+
|
|
108
|
+
Built in the shared runtime, for every archetype that has questions: the six question types and what counts as a right
|
|
109
|
+
answer, at build, in the browser and in the tests alike, with their schema, validation, rendering, engine, end-to-end
|
|
110
|
+
helpers and texts. The quiz asks them; the explainer's quiz-type exercises and the answers of its generated exercises
|
|
111
|
+
use the same. Neither archetype imports the other.
|
|
112
|
+
|
|
113
|
+
```arc42
|
|
114
|
+
:::building-block
|
|
115
|
+
id: bb-questions
|
|
116
|
+
title: Questions
|
|
117
|
+
parent: bb-runtime
|
|
118
|
+
path: runtime/shared/questions
|
|
119
|
+
technology: TypeScript
|
|
120
|
+
:::
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Questions interface
|
|
124
|
+
|
|
125
|
+
The validation, the rendering, the client module and the tests of an archetype with questions use their types,
|
|
126
|
+
rendering, engine and checker.
|
|
127
|
+
|
|
128
|
+
```arc42
|
|
129
|
+
:::interface
|
|
130
|
+
id: if-questions
|
|
131
|
+
title: The question types, rendering, engine and checker
|
|
132
|
+
provider: bb-questions
|
|
133
|
+
protocol: TypeScript imports (runtime/shared/questions), @lernapps/app-templates/questions
|
|
134
|
+
path: runtime/shared/questions
|
|
135
|
+
:::
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Component rules
|
|
139
|
+
|
|
140
|
+
Built in the shared runtime, for every archetype that has Vue components: code checks on the SFC compiler's output of a
|
|
141
|
+
component and the modules of the app it imports (no network, no `eval`, `innerHTML` or `v-html`, imports only from Vue,
|
|
142
|
+
the runtime, the storage, i18n and a11y helpers and the app's own modules, never from a URL, browser globals only once
|
|
143
|
+
mounted). Which modules are the app's own is the archetype's scope: the explainer's components import their own folder,
|
|
144
|
+
the interactive archetype's any file of `src/` and the libraries of its `package.json`.
|
|
145
|
+
|
|
146
|
+
```arc42
|
|
147
|
+
:::building-block
|
|
148
|
+
id: bb-component-rules
|
|
149
|
+
title: Component rules
|
|
150
|
+
parent: bb-runtime
|
|
151
|
+
path: runtime/shared/vue-code.ts
|
|
152
|
+
technology: TypeScript, Vue SFC compiler
|
|
153
|
+
implements: concept-component-rules
|
|
154
|
+
:::
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Component rules interface
|
|
158
|
+
|
|
159
|
+
The validation of an archetype with components runs the checks on its components.
|
|
160
|
+
|
|
161
|
+
```arc42
|
|
162
|
+
:::interface
|
|
163
|
+
id: if-component-rules
|
|
164
|
+
title: The code checks of a component (codeProblems, with the archetype's scope)
|
|
165
|
+
provider: bb-component-rules
|
|
166
|
+
protocol: TypeScript imports (runtime/shared/vue-code.ts)
|
|
167
|
+
path: runtime/shared/vue-code.ts
|
|
168
|
+
:::
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Tooling helpers
|
|
172
|
+
|
|
173
|
+
Built. The parts of `@lernapps/tooling` every app uses, so that rules, helpers and guidance reach the app through
|
|
174
|
+
updates without edits: the preset (`archetypes/shared/preset.ts`: lint with the lernapps rules, type check, format,
|
|
175
|
+
unit tests, the pre-commit staged files, a build with relative URLs); the lint rules (`lint/rules`: learner texts
|
|
176
|
+
German, no request before a click, storage through the wrapper, the Vue component rules); `lernapps check` (`check/`:
|
|
177
|
+
accessible, usable at 360 px, no request before a click, no tracking, links and entry links resolve, and the
|
|
178
|
+
end-to-end tests before a push); the Playwright configuration (`archetypes/shared/playwright.ts`: Chromium at desktop
|
|
179
|
+
width and 360 px on a free port); the small storage (`archetypes/shared/storage.ts`); the announcer and focus helpers
|
|
180
|
+
(`archetypes/shared/a11y.ts`); and i18n (`archetypes/shared/i18n.ts`). The skills are a block of their own
|
|
181
|
+
(`bb-skills`), which the tooling's `skills/` folder is the source of. A large storage (IndexedDB) is left out (`dec-small-storage`).
|
|
182
|
+
|
|
183
|
+
```arc42
|
|
184
|
+
:::ignore H014 @lernapps/tooling is installed in node_modules (node_modules/@lernapps/tooling), which git does not track, and the validator resolves paths only among tracked files (E011)
|
|
185
|
+
:::
|
|
186
|
+
:::building-block
|
|
187
|
+
id: bb-tooling
|
|
188
|
+
title: Tooling helpers
|
|
189
|
+
technology: TypeScript, vite-plus, Playwright (@lernapps/tooling, an optional peer of this package)
|
|
190
|
+
implements: concept-accessibility, concept-component-rules, concept-device-storage, concept-languages, concept-readable-without-js
|
|
191
|
+
:::
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Preset interface
|
|
195
|
+
|
|
196
|
+
The app's vite.config.ts calls `lernapps({ plugins: [<archetype>()] })`; the archetype's runtime uses the preset for
|
|
197
|
+
its own Vite servers.
|
|
198
|
+
|
|
199
|
+
```arc42
|
|
200
|
+
:::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/preset.ts)
|
|
201
|
+
:::
|
|
202
|
+
:::interface
|
|
203
|
+
id: if-preset
|
|
204
|
+
title: lernapps() preset
|
|
205
|
+
provider: bb-tooling
|
|
206
|
+
protocol: TypeScript import, @lernapps/tooling/preset
|
|
207
|
+
:::
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Check command
|
|
211
|
+
|
|
212
|
+
The creator's assistant, the pre-push hook and CI run `lernapps check`; its report names each rule that failed.
|
|
213
|
+
`arc42 validate` in the check is decided, not built.
|
|
214
|
+
|
|
215
|
+
```arc42
|
|
216
|
+
:::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (check/)
|
|
217
|
+
:::
|
|
218
|
+
:::interface
|
|
219
|
+
id: if-lernapps-check
|
|
220
|
+
title: lernapps check command
|
|
221
|
+
provider: bb-tooling
|
|
222
|
+
protocol: CLI, validation report
|
|
223
|
+
:::
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Device storage interface
|
|
227
|
+
|
|
228
|
+
Load, save and remove JSON values through `createStorage`, under the app's prefix in `localStorage`; every access is
|
|
229
|
+
wrapped, so the app keeps working when storage is blocked or full. The decided quota of 100 kB per app is not built.
|
|
230
|
+
|
|
231
|
+
```arc42
|
|
232
|
+
:::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/storage.ts)
|
|
233
|
+
:::
|
|
234
|
+
:::interface
|
|
235
|
+
id: if-device-storage
|
|
236
|
+
title: createStorage(app)
|
|
237
|
+
provider: bb-tooling
|
|
238
|
+
protocol: TypeScript import, @lernapps/tooling/storage
|
|
239
|
+
:::
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Accessibility helpers interface
|
|
243
|
+
|
|
244
|
+
Announcements through the polite live region, focus moves and the reduced-motion query; the end-to-end tests read the
|
|
245
|
+
same live region.
|
|
246
|
+
|
|
247
|
+
```arc42
|
|
248
|
+
:::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/a11y.ts)
|
|
249
|
+
:::
|
|
250
|
+
:::interface
|
|
251
|
+
id: if-a11y
|
|
252
|
+
title: announce, moveFocus, prefersReducedMotion
|
|
253
|
+
provider: bb-tooling
|
|
254
|
+
protocol: TypeScript import, @lernapps/tooling/a11y
|
|
255
|
+
:::
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Translator interface
|
|
259
|
+
|
|
260
|
+
Code that shows learner texts gets them through `translator(messages)`, never as strings in code.
|
|
261
|
+
|
|
262
|
+
```arc42
|
|
263
|
+
:::ignore H014 the interface is in @lernapps/tooling, installed in the untracked node_modules (archetypes/shared/i18n.ts)
|
|
264
|
+
:::
|
|
265
|
+
:::interface
|
|
266
|
+
id: if-translator
|
|
267
|
+
title: translator(messages)
|
|
268
|
+
provider: bb-tooling
|
|
269
|
+
protocol: TypeScript import, @lernapps/tooling/i18n
|
|
270
|
+
:::
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Skills
|
|
274
|
+
|
|
275
|
+
Built in the tooling, one folder per skill. An app commits its skills under `.agents/skills/`: `lernapps-app` for
|
|
276
|
+
every app; the archetype's skill (`lernapps-quiz`, `lernapps-explainer` or `lernapps-interactive`); the content
|
|
277
|
+
skills (`lernapps-content-research`, `lernapps-exercise-patterns`, `lernapps-content-growth`); `lernapps-listing`;
|
|
278
|
+
and the app's own content guide `app-content`. `lernapps update` installs and replaces the `lernapps-*` skills from
|
|
279
|
+
the tooling's `skills/` folder and leaves the app's own alone. They hold the guidance no check can make
|
|
280
|
+
(`dec-skill-interface`).
|
|
281
|
+
|
|
282
|
+
```arc42
|
|
283
|
+
:::ignore H014 the skills are committed in each app under .agents/skills; this repository has none
|
|
284
|
+
:::
|
|
285
|
+
:::building-block
|
|
286
|
+
id: bb-skills
|
|
287
|
+
title: Skills
|
|
288
|
+
technology: Markdown skills (SKILL.md), from the skills/ folder of @lernapps/tooling
|
|
289
|
+
implements: concept-low-stimulation
|
|
290
|
+
:::
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Skills interface
|
|
294
|
+
|
|
295
|
+
The creator's assistant loads `lernapps-app` when it starts work on an app, and its archetype's skill and the content
|
|
296
|
+
skills before it writes what the archetype lets it write.
|
|
297
|
+
|
|
298
|
+
```arc42
|
|
299
|
+
:::ignore H014 the skills are committed in each app under .agents/skills; this repository has none
|
|
300
|
+
:::
|
|
301
|
+
:::interface
|
|
302
|
+
id: if-skills
|
|
303
|
+
title: Skill texts (lernapps-app, the archetype's skill, the content skills, app-content)
|
|
304
|
+
provider: bb-skills
|
|
305
|
+
protocol: Markdown (SKILL.md) loaded by the assistant
|
|
306
|
+
:::
|
|
307
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Runtime View
|
|
2
|
+
|
|
3
|
+
Six scenarios every app shares: opening its pages, learning in the browser, an error path of the device storage,
|
|
4
|
+
the assistant working with the skills, building with the checks, and the end-to-end tests before a push and in CI. Each extension adds its archetype's own
|
|
5
|
+
scenarios (the explainer's include asking the tutor).
|
|
6
|
+
|
|
7
|
+
## Opening the pages
|
|
8
|
+
|
|
9
|
+
A learner, teacher or parent opens `lernapps.net/<app>/`. The host serves static pages the build rendered from what
|
|
10
|
+
the creator wrote; what a page shows without JavaScript depends on the archetype and is in its extension (an
|
|
11
|
+
interactive app's app page shows only a `<noscript>` note). The language switch and the alternates are plain links to
|
|
12
|
+
the same page in the other language tree; an address the app does not have gets the 404 page, which leads to the
|
|
13
|
+
start page.
|
|
14
|
+
|
|
15
|
+
```arc42
|
|
16
|
+
:::runtime-scenario
|
|
17
|
+
id: scenario-pages
|
|
18
|
+
title: Opening the pages
|
|
19
|
+
trigger: A learner, teacher or parent opens the app's address
|
|
20
|
+
involves: bb-render, bb-runtime
|
|
21
|
+
:::
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Learning in the browser
|
|
25
|
+
|
|
26
|
+
The page loads the app's client module; `src/main.ts` calls the archetype's start function, which takes a seed from
|
|
27
|
+
the address where the archetype draws anything at random, shows the learner's progress, announces changes through the
|
|
28
|
+
live region and moves the focus to the feedback. Its texts come in the page's language.
|
|
29
|
+
|
|
30
|
+
```arc42
|
|
31
|
+
:::runtime-scenario
|
|
32
|
+
id: scenario-learn
|
|
33
|
+
title: Learning in the browser
|
|
34
|
+
trigger: The learner opens a page with JavaScript and answers, practises or plays
|
|
35
|
+
involves: bb-shell, bb-tooling
|
|
36
|
+
:::
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Remembering on the device, storage blocked or full
|
|
40
|
+
|
|
41
|
+
An app that remembers something loads and saves JSON values through the storage wrapper, under its own prefix in
|
|
42
|
+
`localStorage`. When the browser blocks storage or it is full, `load` gives nothing and `save` returns false; the app
|
|
43
|
+
keeps working and remembers nothing. The decided quota of 100 kB, beyond which `save` refuses, is not built yet.
|
|
44
|
+
|
|
45
|
+
```arc42
|
|
46
|
+
:::runtime-scenario
|
|
47
|
+
id: scenario-device-storage
|
|
48
|
+
title: Remembering on the device, storage blocked or full
|
|
49
|
+
trigger: The archetype's code loads or saves a value
|
|
50
|
+
involves: bb-shell, bb-tooling
|
|
51
|
+
:::
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Working with the skills
|
|
55
|
+
|
|
56
|
+
The creator's assistant loads the skills the app commits under `.agents/skills/` (`lernapps-app`, the archetype's
|
|
57
|
+
skill, the content skills and the app's own `app-content`), writes what the archetype lets it write and runs
|
|
58
|
+
`lernapps check`. `lernapps update` replaces the `lernapps-*` skills with those of the tooling.
|
|
59
|
+
|
|
60
|
+
```arc42
|
|
61
|
+
:::runtime-scenario
|
|
62
|
+
id: scenario-skills
|
|
63
|
+
title: Working with the skills
|
|
64
|
+
trigger: The creator's assistant starts work on the app
|
|
65
|
+
involves: bb-skills, bb-tooling
|
|
66
|
+
:::
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Building with the checks
|
|
70
|
+
|
|
71
|
+
`vp build` (and `vp dev` on each request) runs the archetype's plugin inside the tooling preset. It validates what
|
|
72
|
+
the creator wrote, runs the archetype's checks (the component rules on any Vue components, the examples through the
|
|
73
|
+
checker where the archetype has them), and only then writes every page in every language, with the shared page trees
|
|
74
|
+
and the runtime's texts, and the 404 page. Any problem fails the build with one line per problem.
|
|
75
|
+
|
|
76
|
+
```arc42
|
|
77
|
+
:::runtime-scenario
|
|
78
|
+
id: scenario-build
|
|
79
|
+
title: Building with the checks
|
|
80
|
+
trigger: The creator, a git hook or CI runs the build
|
|
81
|
+
involves: bb-tooling, bb-archetype-runtime, bb-build, bb-validation, bb-render, bb-runtime-texts, bb-runtime
|
|
82
|
+
:::
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## End-to-end tests before a push
|
|
86
|
+
|
|
87
|
+
`lernapps check --pre-push`, run by the pre-push hook and by CI, serves the built app on a free port and runs the
|
|
88
|
+
archetype's tests in Chromium at desktop width and at 360 px, with reduced motion, with cases derived from what the
|
|
89
|
+
creator wrote. `lernapps check` adds axe, the width check and the request check on the pages it visits.
|
|
90
|
+
|
|
91
|
+
```arc42
|
|
92
|
+
:::runtime-scenario
|
|
93
|
+
id: scenario-e2e
|
|
94
|
+
title: End-to-end tests before a push
|
|
95
|
+
trigger: The pre-push hook or CI runs lernapps check --pre-push
|
|
96
|
+
involves: bb-tooling, bb-e2e, bb-render, bb-shell, bb-runtime-texts
|
|
97
|
+
:::
|
|
98
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Deployment View
|
|
2
|
+
|
|
3
|
+
## Deployment overview
|
|
4
|
+
|
|
5
|
+
Every app is static files: it is built and checked on the creator's machine and again in CI, published to its repo's
|
|
6
|
+
GitHub Pages and run entirely in the learner's browser. There is no server of the app's own; what the app remembers
|
|
7
|
+
stays in the browser's `localStorage`. A pull request gets a preview of the same files. Each extension adds nodes
|
|
8
|
+
below these for its archetype's blocks at build and in the browser; blocks not built yet are listed where they would
|
|
9
|
+
run.
|
|
10
|
+
|
|
11
|
+
Every app gets the same generated Pages workflow (app check, publish, preview) in step 2 of the plan. It is built for
|
|
12
|
+
the explainer and quiz archetypes; the tooling does not have the interactive archetype yet, so an interactive app has
|
|
13
|
+
no generated workflow today. The templates themselves are checked by the CI of `lernapps/app-templates`. The diagram
|
|
14
|
+
shows one representative block per node; each node's section lists all it hosts.
|
|
15
|
+
|
|
16
|
+
```arc42
|
|
17
|
+
:::diagram
|
|
18
|
+
id: deployment-overview
|
|
19
|
+
view: deployment
|
|
20
|
+
notation: mermaid-architecture
|
|
21
|
+
:::
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```mermaid
|
|
25
|
+
architecture-beta
|
|
26
|
+
group env-development(server)[Development]
|
|
27
|
+
group dn-creator-machine(server)[Creator machine] in env-development
|
|
28
|
+
group env-ci(cloud)[CI]
|
|
29
|
+
group dn-ci-runner(server)[GitHub Actions runner] in env-ci
|
|
30
|
+
group env-production(internet)[Production and preview]
|
|
31
|
+
group dn-github-pages(cloud)[GitHub Pages] in env-production
|
|
32
|
+
group dn-pr-preview(cloud)[Pull request preview] in env-production
|
|
33
|
+
group dn-learner-browser(internet)[Learner browser] in env-production
|
|
34
|
+
service bb-tooling(server)[Preset, hooks and lernapps check] in dn-creator-machine
|
|
35
|
+
service bb-build(server)[Build step] in dn-ci-runner
|
|
36
|
+
service bb-render(disk)[Rendered pages] in dn-github-pages
|
|
37
|
+
service bb-runtime(disk)[Page trees] in dn-pr-preview
|
|
38
|
+
service bb-shell(server)[Shell] in dn-learner-browser
|
|
39
|
+
bb-tooling:R --> L:bb-build
|
|
40
|
+
bb-build:R --> L:bb-render
|
|
41
|
+
bb-build:B --> T:bb-runtime
|
|
42
|
+
bb-render:R --> L:bb-shell
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Development
|
|
46
|
+
|
|
47
|
+
The creator's machine, where the creator's AI assistant writes the app.
|
|
48
|
+
|
|
49
|
+
```arc42
|
|
50
|
+
:::deployment-node
|
|
51
|
+
id: env-development
|
|
52
|
+
title: Development
|
|
53
|
+
type: environment
|
|
54
|
+
:::
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Creator's machine
|
|
58
|
+
|
|
59
|
+
`vp dev` serves the pages, rendered on each request. The git hooks the preset installs run the checks before a commit
|
|
60
|
+
(format, lint, type check) and before a push (unit tests, build, checks of the built app, end-to-end tests, in
|
|
61
|
+
Chromium). The assistant loads the skills here. A template folder inside `lernapps/app-templates` gets no hooks of
|
|
62
|
+
its own.
|
|
63
|
+
|
|
64
|
+
```arc42
|
|
65
|
+
:::deployment-node
|
|
66
|
+
id: dn-creator-machine
|
|
67
|
+
title: Creator's machine
|
|
68
|
+
type: device
|
|
69
|
+
parent: env-development
|
|
70
|
+
hosts: bb-tooling, bb-skills, bb-runtime, bb-questions, bb-blocks, bb-component-rules, bb-build, bb-validation, bb-render, bb-runtime-texts, bb-e2e
|
|
71
|
+
:::
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## CI
|
|
75
|
+
|
|
76
|
+
GitHub Actions of the app's repo, on every push and pull request.
|
|
77
|
+
|
|
78
|
+
```arc42
|
|
79
|
+
:::deployment-node
|
|
80
|
+
id: env-ci
|
|
81
|
+
title: CI
|
|
82
|
+
type: environment
|
|
83
|
+
:::
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## GitHub Actions runner
|
|
87
|
+
|
|
88
|
+
The job `app` runs `lernapps check`, the same command as the hooks, and keeps the checked bundle; on `main` the job
|
|
89
|
+
`deploy` publishes it, on a pull request from the repo the job `preview` publishes it as a preview. A change of only
|
|
90
|
+
the plan or only docs checks and publishes nothing.
|
|
91
|
+
|
|
92
|
+
```arc42
|
|
93
|
+
:::deployment-node
|
|
94
|
+
id: dn-ci-runner
|
|
95
|
+
title: GitHub Actions runner
|
|
96
|
+
type: server
|
|
97
|
+
parent: env-ci
|
|
98
|
+
hosts: bb-tooling, bb-runtime, bb-questions, bb-blocks, bb-component-rules, bb-build, bb-validation, bb-render, bb-runtime-texts, bb-e2e
|
|
99
|
+
:::
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Production and preview
|
|
103
|
+
|
|
104
|
+
lernapps.net as learners reach it.
|
|
105
|
+
|
|
106
|
+
```arc42
|
|
107
|
+
:::deployment-node
|
|
108
|
+
id: env-production
|
|
109
|
+
title: Production and preview
|
|
110
|
+
type: environment
|
|
111
|
+
:::
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## GitHub Pages
|
|
115
|
+
|
|
116
|
+
The `gh-pages` branch of the app's repo, served from its root at `lernapps.net/<repo>/` (only a repo of the lernapps
|
|
117
|
+
organisation is served there; any other at its own Pages address). It serves the rendered pages in every language,
|
|
118
|
+
the 404 page, the tutor pages where the tutor is built, and the bundle; the preset builds with relative URLs, so the
|
|
119
|
+
app works under any path.
|
|
120
|
+
|
|
121
|
+
```arc42
|
|
122
|
+
:::deployment-node
|
|
123
|
+
id: dn-github-pages
|
|
124
|
+
title: GitHub Pages
|
|
125
|
+
type: server
|
|
126
|
+
parent: env-production
|
|
127
|
+
hosts: bb-render, bb-runtime, bb-questions, bb-blocks, bb-component-rules
|
|
128
|
+
:::
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Pull request preview
|
|
132
|
+
|
|
133
|
+
The same files below `pr-preview/pr-<number>/` of the app's address, not indexed by search engines, removed when the
|
|
134
|
+
pull request is closed.
|
|
135
|
+
|
|
136
|
+
```arc42
|
|
137
|
+
:::deployment-node
|
|
138
|
+
id: dn-pr-preview
|
|
139
|
+
title: Pull request preview
|
|
140
|
+
type: server
|
|
141
|
+
parent: env-production
|
|
142
|
+
hosts: bb-render, bb-runtime, bb-questions, bb-blocks, bb-component-rules
|
|
143
|
+
:::
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Learner's browser
|
|
147
|
+
|
|
148
|
+
Runs the app's client module: the shell with the archetype's code and the tooling's helpers. `localStorage` of the
|
|
149
|
+
one origin lernapps.net holds what the app remembers, under the app's prefix; nothing leaves the device before a
|
|
150
|
+
click.
|
|
151
|
+
|
|
152
|
+
```arc42
|
|
153
|
+
:::deployment-node
|
|
154
|
+
id: dn-learner-browser
|
|
155
|
+
title: Learner's browser
|
|
156
|
+
type: device
|
|
157
|
+
parent: env-production
|
|
158
|
+
hosts: bb-shell, bb-tooling
|
|
159
|
+
:::
|
|
160
|
+
```
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Cross-cutting Concepts
|
|
2
|
+
|
|
3
|
+
The concepts every lernapps app implements, whatever its archetype. The extensions add their archetype's concepts
|
|
4
|
+
(the explainer's tutor; the interactive app's core and shell, playthroughs, hash routes).
|
|
5
|
+
|
|
6
|
+
## Generic architecture and extensions
|
|
7
|
+
|
|
8
|
+
The archetypes stay separate but share their quality goals, so they share this architecture: the generic part defines
|
|
9
|
+
the shared runtime and the tooling helpers and what every app keeps, and each archetype's extension in its template
|
|
10
|
+
folder adds its runtime and the parts its creator writes, under ids the generic part names (`bb-archetype-runtime`,
|
|
11
|
+
`bb-build`, `bb-render`, `bb-shell`, `bb-e2e`, `if-archetype-content`, …), with its interfaces, decisions, risks and
|
|
12
|
+
terms. An app's architecture is the generic part followed by its archetype's extension, chapter by chapter; an
|
|
13
|
+
interactive app adds its own blocks below its extension's parts in the same way. The building blocks reach two levels,
|
|
14
|
+
roots and their parts, so that every interface can be drawn in a view.
|
|
15
|
+
|
|
16
|
+
```arc42
|
|
17
|
+
:::concept
|
|
18
|
+
id: concept-archetype-extension
|
|
19
|
+
title: Generic architecture plus one extension per archetype
|
|
20
|
+
category: structure
|
|
21
|
+
:::
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Determinism by the seed in the address
|
|
25
|
+
|
|
26
|
+
Whatever an app draws at random comes from a seed in the address, so the same address gives the same order, task or
|
|
27
|
+
round, and a learner, a teacher, a tutor and the tests can open it again: the quiz's order of questions, the
|
|
28
|
+
explainer's tasks by their numbers, an interactive core's states. Each extension says how its archetype uses the seed.
|
|
29
|
+
|
|
30
|
+
```arc42
|
|
31
|
+
:::concept
|
|
32
|
+
id: concept-determinism
|
|
33
|
+
title: Determinism by the seed in the address
|
|
34
|
+
category: testing
|
|
35
|
+
:::
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Readable without JavaScript
|
|
39
|
+
|
|
40
|
+
Every app has static pages that describe it without JavaScript: links, the language switch and the footer are plain
|
|
41
|
+
links, and what needs JavaScript says so in a `<noscript>` note. How much of an app reads without JavaScript depends on
|
|
42
|
+
its archetype: for the quiz and the explainer it is a quality goal of their extensions; an interactive app's start
|
|
43
|
+
page reads without JavaScript, its app page does not.
|
|
44
|
+
|
|
45
|
+
```arc42
|
|
46
|
+
:::concept
|
|
47
|
+
id: concept-readable-without-js
|
|
48
|
+
title: Readable without JavaScript
|
|
49
|
+
category: accessibility
|
|
50
|
+
:::
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Languages
|
|
54
|
+
|
|
55
|
+
Every page exists once per declared language, German at the root and others below `/<language>/`, and an app may
|
|
56
|
+
declare only languages its runtime has texts for. Learner texts are language maps in the creator's data or message
|
|
57
|
+
files by language, reached through the translator, never strings in code.
|
|
58
|
+
|
|
59
|
+
```arc42
|
|
60
|
+
:::concept
|
|
61
|
+
id: concept-languages
|
|
62
|
+
title: Languages
|
|
63
|
+
category: i18n
|
|
64
|
+
:::
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Accessibility by default
|
|
68
|
+
|
|
69
|
+
Pages meet WCAG 2.1 AA and work at 360 px by default; an app that cannot declares its limits in its entry, and only
|
|
70
|
+
then would its findings become warnings (not built yet: they are errors for every app today). Feedback goes through
|
|
71
|
+
the polite live region and the focus moves with the a11y helpers, and `lernapps check` runs axe and the width check on
|
|
72
|
+
the built pages.
|
|
73
|
+
|
|
74
|
+
```arc42
|
|
75
|
+
:::concept
|
|
76
|
+
id: concept-accessibility
|
|
77
|
+
title: Accessibility by default, deviations declared
|
|
78
|
+
category: accessibility
|
|
79
|
+
:::
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Component rules
|
|
83
|
+
|
|
84
|
+
An app's own Vue components (the explainer's components, the interactive UI) and the modules they import are checked
|
|
85
|
+
on the SFC compiler's output at build and by lint rules: no network, no `eval`, `new Function`, `innerHTML` or
|
|
86
|
+
`v-html`, imports only from Vue, the runtime, the storage, i18n and a11y helpers and the app's own files (an
|
|
87
|
+
interactive app's also from the libraries in its dependencies, never from a URL), browser globals only once mounted.
|
|
88
|
+
|
|
89
|
+
```arc42
|
|
90
|
+
:::concept
|
|
91
|
+
id: concept-component-rules
|
|
92
|
+
title: Component rules
|
|
93
|
+
category: security
|
|
94
|
+
:::
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Device storage
|
|
98
|
+
|
|
99
|
+
What an app remembers goes through the storage wrapper into `localStorage`, under the prefix `lernapps:<app>:`,
|
|
100
|
+
because all apps share one origin; every access is wrapped, so blocked or full storage means the app remembers
|
|
101
|
+
nothing and keeps working. The quota of 100 kB per app is decided, not built.
|
|
102
|
+
|
|
103
|
+
```arc42
|
|
104
|
+
:::concept
|
|
105
|
+
id: concept-device-storage
|
|
106
|
+
title: Device storage
|
|
107
|
+
category: persistence
|
|
108
|
+
:::
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Low stimulation (advice)
|
|
112
|
+
|
|
113
|
+
Advice, not a rule or check: the skills recommend no flashing, calm motion and sound off by default, and say why
|
|
114
|
+
(children, attention, seizures); the creator's assistant follows them. Today the skill `lernapps-interactive` gives
|
|
115
|
+
this advice. A settings dialog (less motion, sound, pause) is not in scope now (`dec-no-settings`).
|
|
116
|
+
|
|
117
|
+
```arc42
|
|
118
|
+
:::concept
|
|
119
|
+
id: concept-low-stimulation
|
|
120
|
+
title: Low stimulation (advice)
|
|
121
|
+
category: accessibility
|
|
122
|
+
:::
|
|
123
|
+
```
|