@plasius/learning 0.3.0 → 0.5.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/README.md +32 -0
- package/dist/chunk-2UIOBMJZ.js +44 -0
- package/dist/chunk-2UIOBMJZ.js.map +1 -0
- package/dist/chunk-OXWMIHYI.js +6076 -0
- package/dist/chunk-OXWMIHYI.js.map +1 -0
- package/dist/course-authoring-DImvrK5r.d.cts +514 -0
- package/dist/course-authoring-DImvrK5r.d.ts +514 -0
- package/dist/courses/meteor-shield.cjs +369 -0
- package/dist/courses/meteor-shield.cjs.map +1 -0
- package/dist/courses/meteor-shield.d.cts +6 -0
- package/dist/courses/meteor-shield.d.ts +6 -0
- package/dist/courses/meteor-shield.js +175 -0
- package/dist/courses/meteor-shield.js.map +1 -0
- package/dist/courses/pixel-trail-challenge.cjs +366 -0
- package/dist/courses/pixel-trail-challenge.cjs.map +1 -0
- package/dist/courses/pixel-trail-challenge.d.cts +6 -0
- package/dist/courses/pixel-trail-challenge.d.ts +6 -0
- package/dist/courses/pixel-trail-challenge.js +172 -0
- package/dist/courses/pixel-trail-challenge.js.map +1 -0
- package/dist/courses/rescue-crew-commander.cjs +369 -0
- package/dist/courses/rescue-crew-commander.cjs.map +1 -0
- package/dist/courses/rescue-crew-commander.d.cts +6 -0
- package/dist/courses/rescue-crew-commander.d.ts +6 -0
- package/dist/courses/rescue-crew-commander.js +175 -0
- package/dist/courses/rescue-crew-commander.js.map +1 -0
- package/dist/courses/robot-maze-dash.cjs +355 -0
- package/dist/courses/robot-maze-dash.cjs.map +1 -0
- package/dist/courses/robot-maze-dash.d.cts +6 -0
- package/dist/courses/robot-maze-dash.d.ts +6 -0
- package/dist/courses/robot-maze-dash.js +161 -0
- package/dist/courses/robot-maze-dash.js.map +1 -0
- package/dist/courses/skywing-sprint.cjs +367 -0
- package/dist/courses/skywing-sprint.cjs.map +1 -0
- package/dist/courses/skywing-sprint.d.cts +6 -0
- package/dist/courses/skywing-sprint.d.ts +6 -0
- package/dist/courses/skywing-sprint.js +173 -0
- package/dist/courses/skywing-sprint.js.map +1 -0
- package/dist/courses/star-defender-squadron.cjs +369 -0
- package/dist/courses/star-defender-squadron.cjs.map +1 -0
- package/dist/courses/star-defender-squadron.d.cts +6 -0
- package/dist/courses/star-defender-squadron.d.ts +6 -0
- package/dist/courses/star-defender-squadron.js +175 -0
- package/dist/courses/star-defender-squadron.js.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -504
- package/dist/index.d.ts +3 -504
- package/dist/index.js +44 -6048
- package/dist/index.js.map +1 -1
- package/package.json +31 -1
package/README.md
CHANGED
|
@@ -44,6 +44,38 @@ export remain available unchanged.
|
|
|
44
44
|
|
|
45
45
|
## Complete course and account-save contracts
|
|
46
46
|
|
|
47
|
+
Complete learner curricula are separate lazy entry points. Import
|
|
48
|
+
`{ course, practice }` from `@plasius/learning/courses/robot-maze-dash` for the
|
|
49
|
+
Robot Maze `2.0.0` course: six distinct missions, 54 guided activities, a bounded
|
|
50
|
+
visual starter project, function references, formative concept checks, debugging
|
|
51
|
+
guidance and extensions. Formative answers are learner-safe teaching material;
|
|
52
|
+
they are not protected runtime assessments or completion authority. Hosts verify
|
|
53
|
+
responses, run protected checks and persist evidence independently.
|
|
54
|
+
The root exports `CoursePracticeQuestion` as a type without importing lesson data.
|
|
55
|
+
|
|
56
|
+
The same lazy course boundary also provides `courses/skywing-sprint`,
|
|
57
|
+
`courses/meteor-shield` and `courses/pixel-trail-challenge`. Each has six authored
|
|
58
|
+
missions and 54 activities, 18 formative questions, a real editable `game.js`
|
|
59
|
+
starter and explicit state/input references. Their respective sequences teach
|
|
60
|
+
flight and input timing; vector defence, timed shields and resource accounting;
|
|
61
|
+
and ordered grid movement, bounded placement and moving-tail collisions. Hosts
|
|
62
|
+
must implement and verify each documented game contract before exposing its
|
|
63
|
+
course; lesson publication alone is not evidence of a working playable module.
|
|
64
|
+
|
|
65
|
+
`courses/rescue-crew-commander` adds shared-job ownership, bounded breadth-first
|
|
66
|
+
routes, deterministic dispatch, round-trip energy, delivery conservation and
|
|
67
|
+
recoverable route changes. `courses/star-defender-squadron` adds input/formation
|
|
68
|
+
control, single-hit projectiles, damage grace periods, timed shields and complete
|
|
69
|
+
wave outcomes. Both follow the same six-mission/54-activity contract with authored
|
|
70
|
+
questions, starter projects and references, and require their own host validation.
|
|
71
|
+
|
|
72
|
+
The runtime is supplied separately by `@plasius/learning-runtime`; this package
|
|
73
|
+
does not execute the project or declare host readiness. The seventeen-course
|
|
74
|
+
programme remains in development. This additive content does not alter immutable
|
|
75
|
+
catalogue/pricing records or enable a public host rollout. New hosts compose
|
|
76
|
+
their existing access controls with an independently disabled complete-course
|
|
77
|
+
flag and must validate the full learner journey before enabling it.
|
|
78
|
+
|
|
47
79
|
`LearningCourseV1` defines six missions with nine activities each, editable project
|
|
48
80
|
files, learner guidance and a capstone assessment identifier. Use
|
|
49
81
|
`validateLearningCourse` or `parseLearningCourse` for publication and loading.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LEARNING_COURSE_STAGE_ORDER,
|
|
3
|
+
parseLearningCourse
|
|
4
|
+
} from "./chunk-OXWMIHYI.js";
|
|
5
|
+
|
|
6
|
+
// src/courses/course-authoring.ts
|
|
7
|
+
function authorCourse(header, missions) {
|
|
8
|
+
const course = parseLearningCourse({
|
|
9
|
+
...header,
|
|
10
|
+
schemaVersion: "1",
|
|
11
|
+
moduleVersion: "2.0.0",
|
|
12
|
+
moduleId: `junior-coder.${header.slug}`,
|
|
13
|
+
runtimeId: `${header.slug}.v2`,
|
|
14
|
+
estimatedMinutes: missions.length * 60,
|
|
15
|
+
completionAssessmentId: `${header.slug}.final`,
|
|
16
|
+
completionBadge: { id: `${header.slug}.completed`, title: `${header.title} creator` },
|
|
17
|
+
missions: missions.map((mission, index) => ({
|
|
18
|
+
id: `${header.slug}.m${index + 1}`,
|
|
19
|
+
title: mission.title,
|
|
20
|
+
concepts: mission.concepts,
|
|
21
|
+
goals: mission.goals,
|
|
22
|
+
estimatedMinutes: 60,
|
|
23
|
+
assessmentId: `${header.slug}.m${index + 1}.assessment`,
|
|
24
|
+
extension: mission.extension,
|
|
25
|
+
stages: LEARNING_COURSE_STAGE_ORDER.map((kind) => ({
|
|
26
|
+
id: `${header.slug}.m${index + 1}.${kind}`,
|
|
27
|
+
kind,
|
|
28
|
+
title: `${kind.charAt(0).toUpperCase()}${kind.slice(1)}: ${mission.title}`,
|
|
29
|
+
instruction: mission.activities[kind][0],
|
|
30
|
+
help: mission.activities[kind][1]
|
|
31
|
+
}))
|
|
32
|
+
}))
|
|
33
|
+
});
|
|
34
|
+
const practice = structuredClone(missions.flatMap((mission, index) => ["learn", "predict", "explain"].map((kind) => ({ ...mission.questions[kind], stageId: `${header.slug}.m${index + 1}.${kind}` }))));
|
|
35
|
+
for (const question of practice) {
|
|
36
|
+
if (question.question.trim().length < 20 || question.feedback.trim().length < 40 || question.choices.length !== 3 || question.choices.some((choice) => choice.trim().length < 2) || new Set(question.choices).size !== 3 || !Number.isInteger(question.correctChoice) || question.correctChoice < 0 || question.correctChoice > 2) throw new Error("Invalid course practice question.");
|
|
37
|
+
}
|
|
38
|
+
return { course, practice };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
authorCourse
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=chunk-2UIOBMJZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/courses/course-authoring.ts"],"sourcesContent":["import { LEARNING_COURSE_STAGE_ORDER, parseLearningCourse, type LearningCourseV1 } from \"../course-contracts.js\";\nimport type { MissionStageKindV1 } from \"../contracts.js\";\n\n/** Formative checks are learner-visible teaching material, not protected assessments. */\nexport interface CoursePracticeQuestion {\n stageId: string;\n question: string;\n choices: [string, string, string];\n correctChoice: 0 | 1 | 2;\n feedback: string;\n}\nexport type PracticeDraft = Omit<CoursePracticeQuestion, \"stageId\">;\nexport interface CourseMissionDraft {\n title: string;\n concepts: string[];\n goals: string[];\n extension: string;\n activities: Record<MissionStageKindV1, [instruction: string, help: string]>;\n questions: Record<\"learn\" | \"predict\" | \"explain\", PracticeDraft>;\n}\ntype CourseHeader = Omit<LearningCourseV1, \"schemaVersion\" | \"moduleVersion\" | \"moduleId\" | \"runtimeId\" | \"estimatedMinutes\" | \"completionAssessmentId\" | \"completionBadge\" | \"missions\">;\n\n/** Only identifiers and activity framing are shared; each lesson is independently authored. */\nexport function authorCourse(header: CourseHeader, missions: CourseMissionDraft[]): { course: LearningCourseV1; practice: CoursePracticeQuestion[] } {\n const course = parseLearningCourse({ ...header, schemaVersion: \"1\", moduleVersion: \"2.0.0\", moduleId: `junior-coder.${header.slug}`,\n runtimeId: `${header.slug}.v2`, estimatedMinutes: missions.length * 60,\n completionAssessmentId: `${header.slug}.final`, completionBadge: { id: `${header.slug}.completed`, title: `${header.title} creator` },\n missions: missions.map((mission, index) => ({\n id: `${header.slug}.m${index + 1}`, title: mission.title, concepts: mission.concepts, goals: mission.goals,\n estimatedMinutes: 60, assessmentId: `${header.slug}.m${index + 1}.assessment`, extension: mission.extension,\n stages: LEARNING_COURSE_STAGE_ORDER.map(kind => ({ id: `${header.slug}.m${index + 1}.${kind}`, kind,\n title: `${kind.charAt(0).toUpperCase()}${kind.slice(1)}: ${mission.title}`,\n instruction: mission.activities[kind][0], help: mission.activities[kind][1] })),\n })),\n });\n const practice = structuredClone(missions.flatMap((mission, index) => ([\"learn\", \"predict\", \"explain\"] as const)\n .map(kind => ({ ...mission.questions[kind], stageId: `${header.slug}.m${index + 1}.${kind}` }))));\n for (const question of practice) {\n if (question.question.trim().length < 20 || question.feedback.trim().length < 40\n || question.choices.length !== 3 || question.choices.some(choice => choice.trim().length < 2) || new Set(question.choices).size !== 3\n || !Number.isInteger(question.correctChoice) || question.correctChoice < 0 || question.correctChoice > 2) throw new Error(\"Invalid course practice question.\");\n }\n return { course, practice };\n}\n"],"mappings":";;;;;;AAuBO,SAAS,aAAa,QAAsB,UAAkG;AACnJ,QAAM,SAAS,oBAAoB;AAAA,IAAE,GAAG;AAAA,IAAQ,eAAe;AAAA,IAAK,eAAe;AAAA,IAAS,UAAU,gBAAgB,OAAO,IAAI;AAAA,IAC/H,WAAW,GAAG,OAAO,IAAI;AAAA,IAAO,kBAAkB,SAAS,SAAS;AAAA,IACpE,wBAAwB,GAAG,OAAO,IAAI;AAAA,IAAU,iBAAiB,EAAE,IAAI,GAAG,OAAO,IAAI,cAAc,OAAO,GAAG,OAAO,KAAK,WAAW;AAAA,IACpI,UAAU,SAAS,IAAI,CAAC,SAAS,WAAW;AAAA,MAC1C,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC;AAAA,MAAI,OAAO,QAAQ;AAAA,MAAO,UAAU,QAAQ;AAAA,MAAU,OAAO,QAAQ;AAAA,MACrG,kBAAkB;AAAA,MAAI,cAAc,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC;AAAA,MAAe,WAAW,QAAQ;AAAA,MAClG,QAAQ,4BAA4B,IAAI,WAAS;AAAA,QAAE,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,IAAI,IAAI;AAAA,QAAI;AAAA,QAC7F,OAAO,GAAG,KAAK,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,KAAK,QAAQ,KAAK;AAAA,QACxE,aAAa,QAAQ,WAAW,IAAI,EAAE,CAAC;AAAA,QAAG,MAAM,QAAQ,WAAW,IAAI,EAAE,CAAC;AAAA,MAAE,EAAE;AAAA,IAClF,EAAE;AAAA,EACJ,CAAC;AACD,QAAM,WAAW,gBAAgB,SAAS,QAAQ,CAAC,SAAS,UAAW,CAAC,SAAS,WAAW,SAAS,EAClG,IAAI,WAAS,EAAE,GAAG,QAAQ,UAAU,IAAI,GAAG,SAAS,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;AAClG,aAAW,YAAY,UAAU;AAC/B,QAAI,SAAS,SAAS,KAAK,EAAE,SAAS,MAAM,SAAS,SAAS,KAAK,EAAE,SAAS,MACzE,SAAS,QAAQ,WAAW,KAAK,SAAS,QAAQ,KAAK,YAAU,OAAO,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,IAAI,SAAS,OAAO,EAAE,SAAS,KACjI,CAAC,OAAO,UAAU,SAAS,aAAa,KAAK,SAAS,gBAAgB,KAAK,SAAS,gBAAgB,EAAG,OAAM,IAAI,MAAM,mCAAmC;AAAA,EACjK;AACA,SAAO,EAAE,QAAQ,SAAS;AAC5B;","names":[]}
|