Skip to content

Commit cfb8209

Browse files
committed
docs: add initial draft of "TutorialKit API" docs
1 parent d6a816e commit cfb8209

File tree

4 files changed

+277
-0
lines changed

4 files changed

+277
-0
lines changed

docs/tutorialkit.dev/astro.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ export default defineConfig({
8484
label: 'React Components',
8585
link: '/reference/react-components',
8686
},
87+
{
88+
label: 'TutorialKit API',
89+
link: '/reference/tutorialkit-api',
90+
},
8791
],
8892
},
8993
],
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
---
2+
title: TutorialKit API
3+
description: Use TutorialKit's lower level APIs
4+
---
5+
6+
TutorialKit exposes low level APIs that authors can utilize to provide highly custom experience in their tutorials.
7+
8+
## Tutorial Store
9+
10+
You can access Tutorial Store by importing the `tutorialkit:store` entrypoint.
11+
12+
```ts
13+
import tutorialStore from "tutorialkit:store";
14+
```
15+
16+
### Common types
17+
18+
- `ReadableAtom` from [`nanostores`](https://www.npmjs.com/package/nanostores)
19+
20+
### Properties
21+
22+
#### `previews`
23+
24+
Type: `ReadableAtom<PreviewInfo[]>`
25+
26+
```ts
27+
import type { PreviewSchema } from '@tutorialkit/types';
28+
29+
class PreviewInfo {
30+
readonly portInfo: PortInfo;
31+
title?: string;
32+
pathname?: string;
33+
get url(): string | undefined;
34+
get port(): number;
35+
get baseUrl(): string | undefined;
36+
get ready(): boolean;
37+
static parse(preview: Exclude<PreviewSchema, boolean>[0]): Preview;
38+
static equals(a: PreviewInfo, b: PreviewInfo): boolean;
39+
}
40+
class PortInfo {
41+
readonly port: number;
42+
origin?: string | undefined;
43+
ready: boolean;
44+
}
45+
interface Preview {
46+
port: number;
47+
pathname?: string;
48+
title?: string;
49+
}
50+
```
51+
52+
Instances of the preview tabs.
53+
54+
#### `terminalConfig`
55+
56+
Type: `ReadableAtom<TerminalConfig>`
57+
58+
```ts
59+
import type { TerminalSchema } from '@tutorialkit/types';
60+
import type { WebContainerProcess } from '@webcontainer/api';
61+
62+
class TerminalConfig {
63+
get panels(): TerminalPanel[];
64+
get activePanel(): number;
65+
get defaultOpen(): boolean;
66+
}
67+
68+
class TerminalPanel implements ITerminal {
69+
readonly type: TerminalPanelType;
70+
static panelCount: Record<TerminalPanelType, number>;
71+
static resetCount(): void;
72+
readonly id: string;
73+
readonly title: string;
74+
get terminal(): ITerminal | undefined;
75+
get process(): WebContainerProcess | undefined;
76+
get processOptions(): {
77+
allowRedirects: boolean;
78+
allowCommands: string[] | undefined;
79+
} | undefined;
80+
get cols(): number | undefined;
81+
get rows(): number | undefined;
82+
reset(): void;
83+
write(data: string): void;
84+
onData(callback: (data: string) => void): void;
85+
attachProcess(process: WebContainerProcess): void;
86+
attachTerminal(terminal: ITerminal): void;
87+
}
88+
89+
interface ITerminal {
90+
readonly cols?: number;
91+
readonly rows?: number;
92+
reset: () => void;
93+
write: (data: string) => void;
94+
onData: (cb: (data: string) => void) => void;
95+
}
96+
```
97+
98+
Configuration and instances of the terminal
99+
100+
#### `editorConfig`
101+
102+
Type: `ReadableAtom<EditorConfig>`
103+
104+
```ts
105+
class EditorConfig {
106+
get visible(): boolean;
107+
get fileTree(): {
108+
visible: boolean;
109+
allowEdits: false | string[];
110+
};
111+
}
112+
```
113+
114+
Configuration of the editor and file tree.
115+
116+
#### `currentDocument`
117+
118+
Type: `ReadableAtom<EditorDocument | undefined>`
119+
120+
File that's currently open in the editor.
121+
122+
#### `bootStatus`
123+
124+
Type: `ReadableAtom<BootStatus>`
125+
126+
Status of the webcontainer's booting.
127+
128+
#### `documents`
129+
130+
Type: `ReadableAtom<EditorDocuments>`
131+
132+
Files that are available in the editor.
133+
134+
#### `files`
135+
136+
Type: `ReadableAtom<FileDescriptor[]>`
137+
138+
Paths of the files that are available in the lesson.
139+
140+
#### `template`
141+
142+
Type: `Files | undefined`
143+
144+
Files of the template.
145+
146+
#### `selectedFile`
147+
148+
Type: `ReadableAtom<string | undefined>`
149+
150+
File that's currently selected in the file tree.
151+
152+
#### `lesson`
153+
154+
Type: `Readonly<Lesson> | undefined`
155+
156+
Currently active lesson.
157+
158+
### Methods
159+
160+
#### `hasFileTree`
161+
162+
Type: `() => boolean`
163+
164+
#### `hasEditor`
165+
166+
Type: `() => boolean`
167+
168+
#### `hasPreviews`
169+
170+
Type: `() => boolean`
171+
172+
#### `hasTerminalPanel`
173+
174+
Type: `() => boolean`
175+
176+
#### `hasSolution`
177+
178+
Type: `() => boolean`
179+
180+
#### `unblockBoot`
181+
182+
Type: `() => void`
183+
184+
#### `reset`
185+
186+
Type: `() => void`
187+
188+
#### `solve`
189+
190+
Type: `() => void`
191+
192+
#### `setSelectedFile`
193+
194+
Type: `(filePath: string | undefined) => void`
195+
196+
#### `addFile`
197+
198+
Type: `(filePath: string) => Promise<void>`
199+
200+
#### `addFolder`
201+
202+
Type: `(folderPath: string) => Promise<void>`
203+
204+
#### `updateFile`
205+
206+
Type: `(filePath: string, content: string) => void`
207+
208+
#### `updateFiles`
209+
210+
Type: `(files: Files) => void`
211+
212+
#### `setCurrentDocumentContent`
213+
214+
Type: `(newContent: string) => void`
215+
216+
#### `setCurrentDocumentScrollPosition`
217+
218+
Type: `(position: ScrollPosition) => void`
219+
220+
#### `onTerminalResize`
221+
222+
Type: `(cols: number, rows: number) => void`
223+
224+
#### `onDocumentChanged`
225+
226+
Type: `(filePath: string, callback: (document: Readonly<EditorDocument>) => void) => () => void`
227+
228+
#### `refreshStyles`
229+
230+
Type: `() => void`
231+
232+
#### `takeSnapshot`
233+
234+
Type: `() => { files: Record<string, string> }`
235+
236+
## Tutorial Core
237+
238+
You can access Tutorial Core by importing the `tutorialkit:core` entrypoint.
239+
240+
```ts
241+
import * as core from "tutorialkit:core";
242+
```
243+
244+
The Tutorial Core provides access to webcontainer APIs. You can use it for example to read and modify files on the virtual file system.
245+
246+
### Common Types
247+
248+
- `WebContainer` from [`@webcontainer/api`](https://www.npmjs.com/package/@webcontainer/api)
249+
250+
### Properties
251+
252+
#### `webcontainer`
253+
254+
Type: `Promise<WebContainer>`
255+
256+
Promise that resolves to the webcontainer that's running in the current lesson.

packages/astro/types.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
/* eslint-disable @blitz/lines-around-comment */
2+
13
declare module 'tutorialkit:store' {
24
const tutorialStore: import('@tutorialkit/runtime').TutorialStore;
35

46
export default tutorialStore;
57
}
68

79
declare module 'tutorialkit:core' {
10+
/** Promise that resolves to the webcontainer that's running in the current lesson. */
811
export const webcontainer: Promise<import('@webcontainer/api').WebContainer>;
912
}

packages/runtime/src/store/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export class TutorialStore {
129129
}
130130
}
131131

132+
/** @internal */
132133
setLesson(lesson: Lesson, options: { ssr?: boolean } = {}) {
133134
if (lesson === this._lesson) {
134135
return;
@@ -191,50 +192,62 @@ export class TutorialStore {
191192
);
192193
}
193194

195+
/** Instances of the preview tabs. */
194196
get previews(): ReadableAtom<PreviewInfo[]> {
195197
return this._previewsStore.previews;
196198
}
197199

200+
/** Configuration and instances of the terminal */
198201
get terminalConfig(): ReadableAtom<TerminalConfig> {
199202
return this._terminalStore.terminalConfig;
200203
}
201204

205+
/** Configuration of the editor and file tree */
202206
get editorConfig(): ReadableAtom<EditorConfig> {
203207
return this._editorStore.editorConfig;
204208
}
205209

210+
/** File that's currently open in the editor */
206211
get currentDocument(): ReadableAtom<EditorDocument | undefined> {
207212
return this._editorStore.currentDocument;
208213
}
209214

215+
/** Status of the webcontainer's booting */
210216
get bootStatus(): ReadableAtom<BootStatus> {
211217
return bootStatus;
212218
}
213219

220+
/** Files that are available in the editor. */
214221
get documents(): ReadableAtom<EditorDocuments> {
215222
return this._editorStore.documents;
216223
}
217224

225+
/** Paths of the files that are available in the lesson */
218226
get files(): ReadableAtom<FileDescriptor[]> {
219227
return this._editorStore.files;
220228
}
221229

230+
/** Files of the template */
222231
get template(): Files | undefined {
223232
return this._lessonTemplate;
224233
}
225234

235+
/** File that's currently selected in the file tree */
226236
get selectedFile(): ReadableAtom<string | undefined> {
227237
return this._editorStore.selectedFile;
228238
}
229239

240+
/** Currently active lesson */
230241
get lesson(): Readonly<Lesson> | undefined {
231242
return this._lesson;
232243
}
233244

245+
/** @internal */
234246
get ref(): ReadableAtom<unknown> {
235247
return this._ref;
236248
}
237249

250+
/** @internal */
238251
get themeRef(): ReadableAtom<unknown> {
239252
return this._themeRef;
240253
}
@@ -377,6 +390,7 @@ export class TutorialStore {
377390
this._editorStore.updateScrollPosition(filePath, position);
378391
}
379392

393+
/** @internal */
380394
attachTerminal(id: string, terminal: ITerminal) {
381395
this._terminalStore.attachTerminal(id, terminal);
382396
}

0 commit comments

Comments
 (0)