Skip to content

Commit

Permalink
docs: rest of tutorialkit api docs
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Sep 27, 2024
1 parent 91197ed commit 87e69d0
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 60 deletions.
4 changes: 2 additions & 2 deletions docs/tutorialkit.dev/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export default defineConfig({
link: '/guides/overriding-components/',
},
{
label: 'How to',
link: '/guides/how-to/',
label: 'How to use TutorialKit API',
link: '/guides/how-to-use-tutorialkit-api/',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: How to
title: How to use TutorialKit API
description: "Examples showing how to utilize TutorialKit APIs"
---

Expand Down
109 changes: 65 additions & 44 deletions docs/tutorialkit.dev/src/content/docs/reference/tutorialkit-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: Use TutorialKit's lower level APIs
---

TutorialKit exposes low level APIs that authors can utilize to provide highly custom experience in their tutorials.
These APIs allow authors to control internal parts of TutorialKit. See [How to use TutorialKit API](/guides/how-to-use-tutorialkit-api/) guide for examples.

## Tutorial Store

Expand All @@ -19,11 +20,14 @@ This module may introduce breaking changes in patch and minor version updates. P

You can help us stabilize the API by providing feedback at [Stabilizing `tutorialkit:store` API | Github Discussions](https://github.com/stackblitz/tutorialkit/discussions).
Please let us know how you are using this API.

TODO UPDATE THIS LINK
:::

### Common types

- `ReadableAtom` from [`nanostores`](https://www.npmjs.com/package/nanostores)
- `WebContainerProcess` from [`@webcontainer/api`](https://www.npmjs.com/package/@webcontainer/api)

### Properties

Expand Down Expand Up @@ -159,8 +163,22 @@ Status of the webcontainer's booting.
Type: `ReadableAtom<EditorDocuments>`

```ts
// See type of `EditorDocument` above
import type { FileDescriptor } from '@tutorialkit/types';

type EditorDocuments = Record<string, EditorDocument | undefined>

interface EditorDocument {
value: string | Uint8Array;
loading: boolean;
filePath: string;
type: FileDescriptor['type'];
scroll?: ScrollPosition;
}

interface ScrollPosition {
top: number;
left: number;
}
```

Files that are available in the editor.
Expand All @@ -178,16 +196,6 @@ type FileDescriptor = {
Paths of the files that are available in the lesson.
#### `template`
Type: `Files | undefined`
```ts
type Files = Record<string, string | Uint8Array>
```
Files of the template.
#### `selectedFile`
Type: `ReadableAtom<string | undefined>`
Expand All @@ -199,34 +207,7 @@ File that's currently selected in the file tree.
Type: `Readonly<Lesson> | undefined`
```ts
interface Lesson<T = unknown> {
id: string;
order: number;
data: LessonSchema;
part: {
id: string;
title: string;
};
chapter: {
id: string;
title: string;
};
slug: string;
filepath: string;
editPageLink?: string;
files: FilesRefList;
solution: FilesRefList;
next?: LessonLink;
prev?: LessonLink;
Markdown: T;
}

interface LessonLink {
href: string;
title: string;
}

type FilesRefList = [ref: string, files: string[]]
import type { Lesson } from '@tutorialkit/types';
```

Currently active lesson.
Expand Down Expand Up @@ -273,54 +254,94 @@ Unlock webcontainer's boot process if it was in `'blocked'` state.

Type: `() => void`

Reset changed files back to lesson's initial state.

#### `solve`

Type: `() => void`

Apply lesson solution into the lesson files.

#### `setSelectedFile`

Type: `(filePath: string | undefined) => void`

Set file from file tree as selected.

#### `addFile`

Type: `(filePath: string) => Promise<void>`

Add new file to file tree.
Throws error with message `FILE_EXISTS` if file exists already on file system.

#### `addFolder`

Type: `(folderPath: string) => Promise<void>`

Add new file to file tree.
Throws error with message `FOLDER_EXISTS` if folder exists already on file system.

#### `updateFile`

Type: `(filePath: string, content: string) => void`

#### `updateFiles`
Type: `(files: Files) => void`
Update contents of file.

#### `setCurrentDocumentContent`

Type: `(newContent: string) => void`

Update content of the active file.

#### `setCurrentDocumentScrollPosition`

Type: `(position: ScrollPosition) => void`

```ts
interface ScrollPosition {
top: number;
left: number;
}
```

Update scroll position of the file in editor.

#### `onTerminalResize`

Type: `(cols: number, rows: number) => void`

Callback that should be called when terminal resizes.

#### `onDocumentChanged`

Type: `(filePath: string, callback: (document: Readonly<EditorDocument>) => void) => () => void`

#### `refreshStyles`
```ts
import type { FileDescriptor } from '@tutorialkit/types';

Type: `() => void`
interface EditorDocument {
value: string | Uint8Array;
loading: boolean;
filePath: string;
type: FileDescriptor['type'];
scroll?: ScrollPosition;
}

interface ScrollPosition {
top: number;
left: number;
}
```

Listen for file changes made in the editor.

#### `takeSnapshot`

Type: `() => { files: Record<string, string> }`

Take snapshot of the current state of the lesson.

## Tutorial Core

You can access Tutorial Core by importing the `tutorialkit:core` entrypoint.
Expand Down
25 changes: 12 additions & 13 deletions packages/runtime/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,6 @@ export class TutorialStore {
return this._editorStore.files;
}

/** Files of the template */
get template(): Files | undefined {
return this._lessonTemplate;
}

/** File that's currently selected in the file tree */
get selectedFile(): ReadableAtom<string | undefined> {
return this._editorStore.selectedFile;
Expand Down Expand Up @@ -300,10 +295,12 @@ export class TutorialStore {
return !!this._lesson && Object.keys(this._lesson.solution[1]).length >= 1;
}

/** Unlock webcontainer's boot process if it was in `'blocked'` state */
unblockBoot() {
unblockBoot();
}

/** Reset changed files back to lesson's initial state */
reset() {
const isReady = this.lessonFullyLoaded.value;

Expand All @@ -315,6 +312,7 @@ export class TutorialStore {
this._runner.updateFiles(this._lessonFiles);
}

/** Apply lesson solution into the lesson files */
solve() {
const isReady = this.lessonFullyLoaded.value;

Expand All @@ -328,10 +326,12 @@ export class TutorialStore {
this._runner.updateFiles(files);
}

/** Set file from file tree as selected */
setSelectedFile(filePath: string | undefined) {
this._editorStore.setSelectedFile(filePath);
}

/** Add new file to file tree */
async addFile(filePath: string): Promise<void> {
// always select the existing or newly created file
this.setSelectedFile(filePath);
Expand All @@ -349,6 +349,7 @@ export class TutorialStore {
this._runner.updateFile(filePath, '');
}

/** Add new folder to file tree */
async addFolder(folderPath: string) {
// prevent creating duplicates
if (this._editorStore.files.get().some((file) => file.path.startsWith(folderPath))) {
Expand All @@ -363,6 +364,7 @@ export class TutorialStore {
this._runner.createFolder(folderPath);
}

/** Update contents of file */
updateFile(filePath: string, content: string) {
const hasChanged = this._editorStore.updateFile(filePath, content);

Expand All @@ -371,10 +373,7 @@ export class TutorialStore {
}
}

updateFiles(files: Files) {
this._runner.updateFiles(files);
}

/** Update content of the active file */
setCurrentDocumentContent(newContent: string) {
const filePath = this.currentDocument.get()?.filePath;

Expand All @@ -385,6 +384,7 @@ export class TutorialStore {
this.updateFile(filePath, newContent);
}

/** Update scroll position of the file in editor */
setCurrentDocumentScrollPosition(position: ScrollPosition) {
const editorDocument = this.currentDocument.get();

Expand All @@ -402,21 +402,20 @@ export class TutorialStore {
this._terminalStore.attachTerminal(id, terminal);
}

/** Callback that should be called when terminal resizes */
onTerminalResize(cols: number, rows: number) {
if (cols && rows) {
this._terminalStore.onTerminalResize(cols, rows);
this._runner.onTerminalResize(cols, rows);
}
}

/** Listen for file changes made in the editor */
onDocumentChanged(filePath: string, callback: (document: Readonly<EditorDocument>) => void) {
return this._editorStore.onDocumentChanged(filePath, callback);
}

refreshStyles() {
this._themeRef.set(this._themeRef.get() + 1);
}

/** Take snapshot of the current state of the lesson */
takeSnapshot() {
return this._runner.takeSnapshot();
}
Expand Down

0 comments on commit 87e69d0

Please sign in to comment.