@karagoz/hayali 0.0.0-stage → 0.6.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 +21 -0
- package/dist/karagoz-hayali.css +3 -0
- package/dist/karagoz-hayali.js +3869 -0
- package/dist/karagoz-hayali.umd.cjs +15 -0
- package/dist/karagoz-logo.svg +3 -0
- package/dist/parse.cjs +3 -0
- package/dist/parse.js +521 -0
- package/dist/src/App.vue.d.ts +3 -0
- package/dist/src/callouts.d.ts +28 -0
- package/dist/src/components/KrgzHayali.vue.d.ts +49 -0
- package/dist/src/components/LessonToolbar.vue.d.ts +17 -0
- package/dist/src/components/StepBody.vue.d.ts +7 -0
- package/dist/src/components/StepList.vue.d.ts +15 -0
- package/dist/src/components/StepLockAlert.vue.d.ts +8 -0
- package/dist/src/components/TocDropdown.vue.d.ts +14 -0
- package/dist/src/composables/useCounter.d.ts +4 -0
- package/dist/src/composables/useIsolationWarning.d.ts +5 -0
- package/dist/src/composables/useLessonPosition.d.ts +30 -0
- package/dist/src/composables/useLessonReset.d.ts +34 -0
- package/dist/src/composables/useStepEntry.d.ts +59 -0
- package/dist/src/composables/useStepLocks.d.ts +24 -0
- package/dist/src/examples/DefaultExample.vue.d.ts +3 -0
- package/dist/src/examples/ParserExample.vue.d.ts +3 -0
- package/dist/src/i18n.d.ts +1739 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/layout/breakpoints.d.ts +16 -0
- package/dist/src/layout/layoutCss.d.ts +5 -0
- package/dist/src/lesson.d.ts +9 -0
- package/dist/src/locales/ar.d.ts +25 -0
- package/dist/src/locales/de.d.ts +25 -0
- package/dist/src/locales/en.d.ts +25 -0
- package/dist/src/locales/index.d.ts +1743 -0
- package/dist/src/main.d.ts +3 -0
- package/dist/src/parse/blocks.d.ts +31 -0
- package/dist/src/parse/body.d.ts +7 -0
- package/dist/src/parse/fenceInfo.d.ts +8 -0
- package/dist/src/parse/fileSource.d.ts +18 -0
- package/dist/src/parse/index.d.ts +2 -0
- package/dist/src/parse/parseLesson.d.ts +3 -0
- package/dist/src/parse/resolve.d.ts +37 -0
- package/dist/src/parse/tree.d.ts +11 -0
- package/dist/src/parse/types.d.ts +32 -0
- package/dist/src/typedoc-entry.d.ts +7 -0
- package/dist/src/types.d.ts +69 -0
- package/dist/src/validateLesson.d.ts +22 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts +1943 -0
- package/package.json +87 -3
- package/src/layout.css +218 -0
- package/src/lib.css +50 -0
- package/README.md +0 -3
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Lesson, LineSpec, Step } from '../types';
|
|
2
|
+
export type BlockRule = 'invalid-value' | 'malformed-yaml' | 'unknown-key';
|
|
3
|
+
export declare const BLOCK_PREFIX = "krgz-";
|
|
4
|
+
export declare const LESSON_BLOCK = "krgz-lesson";
|
|
5
|
+
export declare const STEP_BLOCK = "krgz-step";
|
|
6
|
+
/** A problem inside a YAML block; `line` is 0-based in the lesson file. */
|
|
7
|
+
export interface BlockIssue {
|
|
8
|
+
rule: BlockRule;
|
|
9
|
+
line: number;
|
|
10
|
+
column: number;
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
13
|
+
type Where = Pick<BlockIssue, 'line' | 'column'>;
|
|
14
|
+
interface ParsedBlock {
|
|
15
|
+
data: Record<string, unknown> | undefined;
|
|
16
|
+
/** Position of every key and list item, by dotted path such as `editor.highlight.0.lines`. */
|
|
17
|
+
at: (path: string) => Where;
|
|
18
|
+
}
|
|
19
|
+
/** Parses the YAML of a block. `firstLine` is the 0-based lesson line the YAML text starts on. */
|
|
20
|
+
export declare const parseYamlBlock: (text: string, firstLine: number, issues: BlockIssue[]) => ParsedBlock;
|
|
21
|
+
/** `1-7, 13-17` to a `LineSpec`, or `undefined` if it is not that shorthand. */
|
|
22
|
+
export declare const parseLinesShorthand: (text: string) => LineSpec | undefined;
|
|
23
|
+
/** Reports a problem at the key or list item with this dotted path. */
|
|
24
|
+
export type NoteBlockIssue = (rule: BlockRule, path: string, message: string) => void;
|
|
25
|
+
export declare const readLessonBlock: (data: Record<string, unknown>, report: NoteBlockIssue) => Pick<Lesson, "immutable">;
|
|
26
|
+
/** The directives of a step block: `Step` fields, plus `carry`, which only the parser acts on. */
|
|
27
|
+
export type StepBlock = Partial<Pick<Step, 'removals' | 'locks' | 'editor' | 'preview'>> & {
|
|
28
|
+
carry?: string;
|
|
29
|
+
};
|
|
30
|
+
export declare const readStepBlock: (data: Record<string, unknown>, report: NoteBlockIssue) => StepBlock;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A 0-based `[start, end)` range of lines. */
|
|
2
|
+
export type LineRange = [start: number, end: number];
|
|
3
|
+
/**
|
|
4
|
+
* The Markdown of `lines[start, end)` without the `cuts` (the fences that became files and blocks), trimmed. A cut
|
|
5
|
+
* between two blank lines does not leave a double gap.
|
|
6
|
+
*/
|
|
7
|
+
export declare const sliceBody: (lines: string[], start: number, end: number, cuts: LineRange[]) => string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface FenceInfo {
|
|
2
|
+
/** Bare words in order, e.g. `['css']` or `['yaml', 'krgz-step']`. */
|
|
3
|
+
words: string[];
|
|
4
|
+
/** `key=value` pairs; a bare `file` counts as `file=` with an empty value. Later keys win. */
|
|
5
|
+
attrs: Map<string, string>;
|
|
6
|
+
}
|
|
7
|
+
/** Splits a fence info string into words, with `key=value` pairs where the value may be quoted. */
|
|
8
|
+
export declare const parseFenceInfo: (info: string) => FenceInfo;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FileSource } from './resolve';
|
|
2
|
+
import type { ParseIssueRule } from './types';
|
|
3
|
+
export interface FileSourceContext {
|
|
4
|
+
/** Reports an issue on the fence being read. */
|
|
5
|
+
fail: (rule: ParseIssueRule, message: string) => void;
|
|
6
|
+
resolveSrc?: (path: string) => string | undefined;
|
|
7
|
+
/** Collects the normalized `src=` paths asked of `resolveSrc`, once each. */
|
|
8
|
+
srcPaths: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Where a file fence gets its content: its body, `from=` or `src=`, never more than one. Reports why and returns
|
|
12
|
+
* `undefined` when the fence cannot be used.
|
|
13
|
+
*/
|
|
14
|
+
export declare const readFileSource: (fence: {
|
|
15
|
+
attrs: Map<string, string>;
|
|
16
|
+
content: string;
|
|
17
|
+
path: string;
|
|
18
|
+
}, { fail, resolveSrc, srcPaths }: FileSourceContext) => FileSource | undefined;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ParseLessonOptions, ParseLessonResult } from './types';
|
|
2
|
+
/** Never throws: if compiling fails on pathological input, the result is an empty lesson with one issue. */
|
|
3
|
+
export declare const parseLesson: (source: string, options?: ParseLessonOptions) => ParseLessonResult;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AdjustmentsTree } from '../types';
|
|
2
|
+
import type { ParseIssue, ParseIssueRule } from './types';
|
|
3
|
+
export type FileSource = {
|
|
4
|
+
kind: 'literal';
|
|
5
|
+
contents: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'from';
|
|
8
|
+
ref: string;
|
|
9
|
+
};
|
|
10
|
+
export interface FileEntry {
|
|
11
|
+
path: string;
|
|
12
|
+
/** 0-based line of the fence. */
|
|
13
|
+
line: number;
|
|
14
|
+
source: FileSource;
|
|
15
|
+
}
|
|
16
|
+
/** The files declared for the base tree or for one step, by normalized path. */
|
|
17
|
+
export interface Scope {
|
|
18
|
+
chapterId?: string;
|
|
19
|
+
stepId?: string;
|
|
20
|
+
entries: Map<string, FileEntry>;
|
|
21
|
+
/** Normalized paths in the step's `removals`. */
|
|
22
|
+
removals?: string[];
|
|
23
|
+
/** The step's `carry:` as written, with the 0-based position of the key. */
|
|
24
|
+
carry?: {
|
|
25
|
+
ref: string;
|
|
26
|
+
line: number;
|
|
27
|
+
column: number;
|
|
28
|
+
};
|
|
29
|
+
/** Set while resolving, once `carry` names a real step and forms no cycle. */
|
|
30
|
+
carryTarget?: Scope;
|
|
31
|
+
}
|
|
32
|
+
export type Report = (rule: ParseIssueRule, line: number, message: string, extra?: Partial<Pick<ParseIssue, 'chapterId' | 'stepId' | 'path' | 'column' | 'severity'>>) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Expands every `from=` reference and builds each scope's tree. A file that cannot be resolved is reported and left
|
|
35
|
+
* out. Only scopes with at least one resolved file appear in the result.
|
|
36
|
+
*/
|
|
37
|
+
export declare const resolveFiles: (base: Scope, steps: Scope[], report: Report) => Map<Scope, AdjustmentsTree>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AdjustmentsTree } from '../types';
|
|
2
|
+
/** Splits a root-relative path into its segments, dropping empty and `.` ones. */
|
|
3
|
+
export declare const segments: (path: string) => string[];
|
|
4
|
+
/** Normalizes a path to `a/b/c`, or `''` when nothing is left. */
|
|
5
|
+
export declare const normalizePath: (path: string) => string;
|
|
6
|
+
/** Whether `path` or one of its parent directories is already a file in `taken`, or it is a directory of one. */
|
|
7
|
+
export declare const conflicts: (taken: Iterable<string>, path: string) => boolean;
|
|
8
|
+
/** Puts a file into the tree, creating directories on the way. The path must not `conflict` with existing ones. */
|
|
9
|
+
export declare const setFile: (tree: AdjustmentsTree, path: string, contents: string) => void;
|
|
10
|
+
/** A `src=` path as a clean relative POSIX path, or `undefined` if it is empty, absolute or escapes the lesson folder. */
|
|
11
|
+
export declare const normalizeSrcPath: (raw: string) => string | undefined;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Lesson } from '../types';
|
|
2
|
+
import type { BlockRule } from './blocks';
|
|
3
|
+
export type ParseIssueRule = BlockRule | 'file-outside-step' | 'carry-cycle' | 'carry-drops-removals' | 'carry-unknown-step' | 'conflicting-file-source' | 'duplicate-file' | 'duplicate-id' | 'duplicate-lesson-block' | 'duplicate-step-block' | 'empty-chapter' | 'invalid-src' | 'invalid-id' | 'misplaced-lesson-block' | 'misplaced-step-block' | 'missing-file-path' | 'missing-id' | 'parser-failure' | 'ref-cycle' | 'ref-missing-path' | 'ref-unknown-step' | 'ref-with-body' | 'src-with-body' | 'step-outside-chapter' | 'unclosed-fence' | 'unresolved-src' | 'unknown-fence';
|
|
4
|
+
/** A problem found while parsing a lesson file. Distinct from a `LessonIssue`, which is found by `validateLesson`. */
|
|
5
|
+
export interface ParseIssue {
|
|
6
|
+
rule: ParseIssueRule;
|
|
7
|
+
severity: 'error' | 'warning';
|
|
8
|
+
message: string;
|
|
9
|
+
/** 1-based. */
|
|
10
|
+
line: number;
|
|
11
|
+
column?: number;
|
|
12
|
+
chapterId?: string;
|
|
13
|
+
stepId?: string;
|
|
14
|
+
path?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ParseLessonOptions {
|
|
17
|
+
/** Reads a `src=` file; the path is relative to the lesson file. Without it any `src=` is unresolved. */
|
|
18
|
+
resolveSrc?: (path: string) => string | undefined;
|
|
19
|
+
}
|
|
20
|
+
export interface ParseLessonResult {
|
|
21
|
+
/** Best-effort: whatever could be built, even when `issues` holds errors. */
|
|
22
|
+
lesson: Lesson;
|
|
23
|
+
issues: ParseIssue[];
|
|
24
|
+
/** Normalized `src=` paths asked of `resolveSrc`, for HMR/cache invalidation. */
|
|
25
|
+
srcPaths: string[];
|
|
26
|
+
/** 1-based Markdown line of a chapter, step or file, or `undefined` if it is not in the file. */
|
|
27
|
+
locate(target: {
|
|
28
|
+
chapterId: string;
|
|
29
|
+
stepId?: string;
|
|
30
|
+
path?: string;
|
|
31
|
+
}): number | undefined;
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { calloutPlugin, createCalloutRegistry } from './callouts';
|
|
2
|
+
export type { CalloutDefinition, CalloutRegistry } from './callouts';
|
|
3
|
+
export { i18nMessages } from './locales';
|
|
4
|
+
export type { FullLayoutFrom } from './layout/breakpoints';
|
|
5
|
+
export type { AdjustmentsTree, Chapter, EditorDirective, Lesson, LineSpec, PathPattern, Position, Step, } from './types';
|
|
6
|
+
export { validateLesson } from './validateLesson';
|
|
7
|
+
export type { LessonIssue, LessonIssueRule } from './validateLesson';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** Glob-style path pattern, e.g. `package.json` or `src/**`. */
|
|
2
|
+
export type PathPattern = string;
|
|
3
|
+
/** Adjustments tree: nested directories to file contents, as accepted by WebContainer `mount()`. */
|
|
4
|
+
export interface AdjustmentsTree {
|
|
5
|
+
[name: string]: {
|
|
6
|
+
file: {
|
|
7
|
+
contents: string;
|
|
8
|
+
};
|
|
9
|
+
} | {
|
|
10
|
+
directory: AdjustmentsTree;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/** 1-based, inclusive: a line, a `[from, to]` range, or a list of either. */
|
|
14
|
+
export type LineSpec = number | [from: number, to: number] | (number | [number, number])[];
|
|
15
|
+
/** Per-step editor instructions, applied on every entry to the step. */
|
|
16
|
+
export interface EditorDirective {
|
|
17
|
+
/** Files to open; the last one is focused. Optionally with a line to go to. */
|
|
18
|
+
open?: (string | {
|
|
19
|
+
path: string;
|
|
20
|
+
line?: number;
|
|
21
|
+
})[];
|
|
22
|
+
/** Files to close, or `'all'`. */
|
|
23
|
+
close?: string[] | 'all';
|
|
24
|
+
/** Lines to highlight. */
|
|
25
|
+
highlight?: {
|
|
26
|
+
path: string;
|
|
27
|
+
lines: LineSpec;
|
|
28
|
+
}[];
|
|
29
|
+
}
|
|
30
|
+
export interface Step {
|
|
31
|
+
/** Author-supplied, unique within its chapter. Never derived from title text. */
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
/** Markdown body. */
|
|
35
|
+
body: string;
|
|
36
|
+
/** Files added/changed by this step, overlaid on the lesson base tree. */
|
|
37
|
+
adjustments?: AdjustmentsTree;
|
|
38
|
+
/** Paths deleted when entering this step. */
|
|
39
|
+
removals?: string[];
|
|
40
|
+
/** Paths locked (UI-only) for this step. */
|
|
41
|
+
locks?: PathPattern[];
|
|
42
|
+
/** Editor directives applied on entry to this step. */
|
|
43
|
+
editor?: EditorDirective;
|
|
44
|
+
/** Preview to show on entry to this step. `url` is root-relative and may carry a query/hash. */
|
|
45
|
+
preview?: {
|
|
46
|
+
url: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface Chapter {
|
|
50
|
+
/** Author-supplied, unique within the lesson. Never derived from title text. */
|
|
51
|
+
id: string;
|
|
52
|
+
title: string;
|
|
53
|
+
steps: Step[];
|
|
54
|
+
}
|
|
55
|
+
export interface Lesson {
|
|
56
|
+
chapters: Chapter[];
|
|
57
|
+
/** Base tree mounted at boot, split into immutable and resettable tiers by `immutable`. */
|
|
58
|
+
files?: AdjustmentsTree;
|
|
59
|
+
/** Paths mounted once and never reset. */
|
|
60
|
+
immutable?: PathPattern[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A step within a lesson. Step IDs are unique only within their chapter, so both IDs are needed. A position that
|
|
64
|
+
* names no existing step falls back to the first step of the lesson.
|
|
65
|
+
*/
|
|
66
|
+
export interface Position {
|
|
67
|
+
chapterId: string;
|
|
68
|
+
stepId: string;
|
|
69
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Lesson } from './types';
|
|
2
|
+
export type LessonIssueRule = 'invalid-path' | 'invalid-preview-url' | 'line-out-of-range' | 'malformed-lines' | 'missing-file' | 'removed-path';
|
|
3
|
+
export interface LessonIssue {
|
|
4
|
+
rule: LessonIssueRule;
|
|
5
|
+
chapterId: string;
|
|
6
|
+
stepId: string;
|
|
7
|
+
/** Normalized offending path, when the issue is about one. */
|
|
8
|
+
path?: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolves a LineSpec to inclusive `[from, to]` ranges, or `undefined` if it is malformed. An ascending pair of numbers
|
|
13
|
+
* is a range; any other non-empty array is a list of lines and `[from, to]` pairs (not nested further).
|
|
14
|
+
*/
|
|
15
|
+
export declare const toRanges: (spec: unknown) => [number, number][] | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Checks a lesson for authoring mistakes without a browser. Resolves each step's tree (base files plus the step's own
|
|
18
|
+
* adjustments, minus its removals; steps are not cumulative) and validates the step's editor directives and preview.
|
|
19
|
+
*
|
|
20
|
+
* @returns the issues found; an empty array means the lesson is valid.
|
|
21
|
+
*/
|
|
22
|
+
export declare const validateLesson: (lesson: Lesson) => LessonIssue[];
|