Skip to content

Commit a9c77c4

Browse files
committed
docs: add example of tutorialkit:core usage
1 parent b05fc55 commit a9c77c4

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed
Binary file not shown.

docs/tutorialkit.dev/src/content/docs/guides/using-low-level-apis.mdx

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Using low level APIs
33
---
4-
4+
import taskListVideo from "./images/tk-task-list.webm";
55
import { HelpButton } from "@components/react-examples/HelpButton";
66
import '@tutorialkit/astro/default-theme.css';
77

@@ -57,7 +57,7 @@ import { useState } from "react";
5757
export function HelpButton() {
5858
const [message, setMessage] = useState<string | null>(null);
5959

60-
async function onClick() {
60+
function onClick() {
6161
const files = tutorialStore.documents.value;
6262
const index = files["/index.js"].value as string;
6363

@@ -102,3 +102,89 @@ import { HelpButton } from "@/components/HelpButton";
102102
In this lesson we'll learn about...
103103
Click this button if you need help: <HelpButton client:load />
104104
```
105+
106+
## Tutorial Core
107+
108+
You can access Tutorial Core by importing the `tutorialkit:core` entrypoint.
109+
110+
```ts
111+
import * as core from "tutorialkit:core";
112+
```
113+
114+
The Tutorial Core provides access to webcontainer APIs. You can use it for example to read and modify files on the virtual file system.
115+
116+
```ts
117+
import * as core from "tutorialkit:core";
118+
119+
const webcontainer = await core.webcontainer;
120+
const contents = await webcontainer.fs.readdir("/", "utf8");
121+
122+
console.log(contents);
123+
[
124+
"index.html",
125+
"node_modules",
126+
"package-lock.json",
127+
"package.json",
128+
"vite.config.ts"
129+
]
130+
```
131+
132+
133+
### Example usage in React component
134+
135+
Here is an example of custom React component that looks for updates in `/index.js` and provides user information about their lesson status.
136+
137+
<video src={taskListVideo} controls />
138+
139+
```tsx title="src/components/TaskList.tsx"
140+
import * as core from "tutorialkit:core";
141+
import { useEffect, useState } from "react";
142+
143+
export function TaskList() {
144+
const [hasDefaultExport, setDefaultExport] = useState<boolean>(false);
145+
const [hasSumFunction, setSumFunction] = useState<boolean>(false);
146+
147+
useEffect(() => {
148+
const unsubscribe = subscribeFileChanges("/index.js", (content) => {
149+
// Naive text based checking just for example. Use proper AST analysis in real lessons.
150+
setDefaultExport(content.includes("export default"));
151+
setSumFunction(content.includes("function sum"));
152+
});
153+
154+
return () => unsubscribe();
155+
}, []);
156+
157+
return (
158+
<ol>
159+
<li>Add default export to index.js {hasDefaultExport ? "" : ""}</li>
160+
<li>Add <code>function sum</code> to index.js {hasSumFunction ? "" : ""}</li>
161+
</ol>
162+
);
163+
}
164+
165+
function subscribeFileChanges(filename: string, callback: (content: string) => void) {
166+
const controller = new AbortController();
167+
168+
core.webcontainer.then((webcontainer) => {
169+
const watcher = webcontainer.fs.watch(filename, async () => {
170+
const content = await webcontainer.fs.readFile(filename, "utf8");
171+
callback(content);
172+
});
173+
174+
controller.signal.addEventListener("abort", () => watcher.close());
175+
});
176+
177+
return () => controller.abort();
178+
}
179+
```
180+
181+
```mdx title="content.mdx"
182+
---
183+
type: lesson
184+
title: Lesson Topic
185+
---
186+
187+
import { TaskList } from "@/components/TaskList";
188+
189+
<TaskList client:load />
190+
```

0 commit comments

Comments
 (0)