@sanity-labs/slides 0.0.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 +241 -0
- package/SKILL.md +119 -0
- package/dist/cli.d.ts +38 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +386 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/components.d.ts +179 -0
- package/dist/core/components.d.ts.map +1 -0
- package/dist/core/components.js +40 -0
- package/dist/core/components.js.map +1 -0
- package/dist/core/fake-runtime.d.ts +138 -0
- package/dist/core/fake-runtime.d.ts.map +1 -0
- package/dist/core/fake-runtime.js +210 -0
- package/dist/core/fake-runtime.js.map +1 -0
- package/dist/core/font-resolver.d.ts +28 -0
- package/dist/core/font-resolver.d.ts.map +1 -0
- package/dist/core/font-resolver.js +30 -0
- package/dist/core/font-resolver.js.map +1 -0
- package/dist/core/geometry.d.ts +71 -0
- package/dist/core/geometry.d.ts.map +1 -0
- package/dist/core/geometry.js +44 -0
- package/dist/core/geometry.js.map +1 -0
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +20 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/manifest.d.ts +123 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +43 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/core/op-translator-pptx.d.ts +150 -0
- package/dist/core/op-translator-pptx.d.ts.map +1 -0
- package/dist/core/op-translator-pptx.js +245 -0
- package/dist/core/op-translator-pptx.js.map +1 -0
- package/dist/core/pptx-runtime.d.ts +103 -0
- package/dist/core/pptx-runtime.d.ts.map +1 -0
- package/dist/core/pptx-runtime.js +405 -0
- package/dist/core/pptx-runtime.js.map +1 -0
- package/dist/core/reconciler.d.ts +113 -0
- package/dist/core/reconciler.d.ts.map +1 -0
- package/dist/core/reconciler.js +453 -0
- package/dist/core/reconciler.js.map +1 -0
- package/dist/core/runtime.d.ts +161 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +11 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/template.d.ts +32 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +3 -0
- package/dist/core/template.js.map +1 -0
- package/dist/dev/auto-examples.d.ts +6 -0
- package/dist/dev/auto-examples.d.ts.map +1 -0
- package/dist/dev/auto-examples.js +79 -0
- package/dist/dev/auto-examples.js.map +1 -0
- package/dist/dev/bin/slides-dev.d.ts +3 -0
- package/dist/dev/bin/slides-dev.d.ts.map +1 -0
- package/dist/dev/bin/slides-dev.js +87 -0
- package/dist/dev/bin/slides-dev.js.map +1 -0
- package/dist/dev/bin/slides-dev.mjs +24 -0
- package/dist/dev/compose-deck.d.ts +18 -0
- package/dist/dev/compose-deck.d.ts.map +1 -0
- package/dist/dev/compose-deck.js +19 -0
- package/dist/dev/compose-deck.js.map +1 -0
- package/dist/dev/deck-viewer.d.ts +19 -0
- package/dist/dev/deck-viewer.d.ts.map +1 -0
- package/dist/dev/deck-viewer.js +237 -0
- package/dist/dev/deck-viewer.js.map +1 -0
- package/dist/dev/dev-server/client/entry.d.ts +2 -0
- package/dist/dev/dev-server/client/entry.d.ts.map +1 -0
- package/dist/dev/dev-server/client/entry.js +12 -0
- package/dist/dev/dev-server/client/entry.js.map +1 -0
- package/dist/dev/dev-server/output.d.ts +8 -0
- package/dist/dev/dev-server/output.d.ts.map +1 -0
- package/dist/dev/dev-server/output.js +32 -0
- package/dist/dev/dev-server/output.js.map +1 -0
- package/dist/dev/dev-server/server-only-stub.d.ts +7 -0
- package/dist/dev/dev-server/server-only-stub.d.ts.map +1 -0
- package/dist/dev/dev-server/server-only-stub.js +12 -0
- package/dist/dev/dev-server/server-only-stub.js.map +1 -0
- package/dist/dev/dev-server/start.d.ts +14 -0
- package/dist/dev/dev-server/start.d.ts.map +1 -0
- package/dist/dev/dev-server/start.js +135 -0
- package/dist/dev/dev-server/start.js.map +1 -0
- package/dist/dev/index.d.ts +5 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +5 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/lib/cn.d.ts +3 -0
- package/dist/dev/lib/cn.d.ts.map +1 -0
- package/dist/dev/lib/cn.js +3 -0
- package/dist/dev/lib/cn.js.map +1 -0
- package/dist/dev/slide-canvas.d.ts +12 -0
- package/dist/dev/slide-canvas.d.ts.map +1 -0
- package/dist/dev/slide-canvas.js +123 -0
- package/dist/dev/slide-canvas.js.map +1 -0
- package/dist/dev/styles.css +37 -0
- package/dist/dev/ui/icon-button.d.ts +12 -0
- package/dist/dev/ui/icon-button.d.ts.map +1 -0
- package/dist/dev/ui/icon-button.js +6 -0
- package/dist/dev/ui/icon-button.js.map +1 -0
- package/dist/dev/ui/kbd.d.ts +6 -0
- package/dist/dev/ui/kbd.d.ts.map +1 -0
- package/dist/dev/ui/kbd.js +4 -0
- package/dist/dev/ui/kbd.js.map +1 -0
- package/dist/dev/ui/text-button.d.ts +10 -0
- package/dist/dev/ui/text-button.d.ts.map +1 -0
- package/dist/dev/ui/text-button.js +6 -0
- package/dist/dev/ui/text-button.js.map +1 -0
- package/dist/dev/url-state.d.ts +7 -0
- package/dist/dev/url-state.d.ts.map +1 -0
- package/dist/dev/url-state.js +13 -0
- package/dist/dev/url-state.js.map +1 -0
- package/dist/dev/use-keyboard-nav.d.ts +17 -0
- package/dist/dev/use-keyboard-nav.d.ts.map +1 -0
- package/dist/dev/use-keyboard-nav.js +53 -0
- package/dist/dev/use-keyboard-nav.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/errors.d.ts +57 -0
- package/dist/mcp/errors.d.ts.map +1 -0
- package/dist/mcp/errors.js +44 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/index.d.ts +29 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +29 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/naming.d.ts +37 -0
- package/dist/mcp/naming.d.ts.map +1 -0
- package/dist/mcp/naming.js +43 -0
- package/dist/mcp/naming.js.map +1 -0
- package/dist/mcp/render.d.ts +45 -0
- package/dist/mcp/render.d.ts.map +1 -0
- package/dist/mcp/render.js +77 -0
- package/dist/mcp/render.js.map +1 -0
- package/dist/mcp/schema.d.ts +54 -0
- package/dist/mcp/schema.d.ts.map +1 -0
- package/dist/mcp/schema.js +55 -0
- package/dist/mcp/schema.js.map +1 -0
- package/dist/mcp/server.d.ts +63 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +196 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/scaffold/index.d.ts +39 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +84 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/template-base/README.md +134 -0
- package/dist/scaffold/template-base/_gitignore +4 -0
- package/dist/scaffold/template-base/package.json +35 -0
- package/dist/scaffold/template-base/src/components/Cover.tsx +30 -0
- package/dist/scaffold/template-base/src/index.ts +27 -0
- package/dist/scaffold/template-base/src/preview.tsx +9 -0
- package/dist/scaffold/template-base/tsconfig.build.json +10 -0
- package/dist/scaffold/template-base/tsconfig.json +18 -0
- package/package.json +164 -0
- package/src/__tests__/fixtures/test-template/index.tsx +77 -0
- package/src/__tests__/pptx-mcp.test.ts +85 -0
- package/src/__tests__/pptx-smoke.test.ts +45 -0
- package/src/__tests__/preview.test.ts +28 -0
- package/src/cli.ts +426 -0
- package/src/core/__snapshots__/reconciler.test.ts.snap +320 -0
- package/src/core/components.test.ts +57 -0
- package/src/core/components.ts +196 -0
- package/src/core/fake-runtime.test.ts +174 -0
- package/src/core/fake-runtime.ts +302 -0
- package/src/core/font-resolver.ts +46 -0
- package/src/core/geometry.test.ts +58 -0
- package/src/core/geometry.ts +91 -0
- package/src/core/index.ts +69 -0
- package/src/core/manifest.test.ts +33 -0
- package/src/core/manifest.ts +150 -0
- package/src/core/op-translator-pptx.test.ts +204 -0
- package/src/core/op-translator-pptx.ts +365 -0
- package/src/core/pptx-runtime.test.ts +137 -0
- package/src/core/pptx-runtime.ts +504 -0
- package/src/core/reconciler.test.ts +644 -0
- package/src/core/reconciler.ts +603 -0
- package/src/core/runtime.ts +150 -0
- package/src/core/template.test.ts +136 -0
- package/src/core/template.ts +37 -0
- package/src/dev/auto-examples.ts +89 -0
- package/src/dev/bin/slides-dev.mjs +24 -0
- package/src/dev/bin/slides-dev.ts +101 -0
- package/src/dev/compose-deck.test.ts +68 -0
- package/src/dev/compose-deck.ts +40 -0
- package/src/dev/deck-viewer.tsx +677 -0
- package/src/dev/dev-server/client/entry.tsx +15 -0
- package/src/dev/dev-server/client/index.html +24 -0
- package/src/dev/dev-server/output.ts +37 -0
- package/src/dev/dev-server/server-only-stub.ts +12 -0
- package/src/dev/dev-server/start.ts +155 -0
- package/src/dev/index.ts +4 -0
- package/src/dev/lib/cn.ts +3 -0
- package/src/dev/slide-canvas.test.tsx +66 -0
- package/src/dev/slide-canvas.tsx +170 -0
- package/src/dev/styles.css +37 -0
- package/src/dev/ui/icon-button.tsx +31 -0
- package/src/dev/ui/kbd.tsx +20 -0
- package/src/dev/ui/text-button.tsx +31 -0
- package/src/dev/url-state.test.ts +22 -0
- package/src/dev/url-state.ts +17 -0
- package/src/dev/use-keyboard-nav.ts +64 -0
- package/src/index.ts +17 -0
- package/src/mcp/errors.test.ts +51 -0
- package/src/mcp/errors.ts +76 -0
- package/src/mcp/index.ts +45 -0
- package/src/mcp/naming.test.ts +39 -0
- package/src/mcp/naming.ts +49 -0
- package/src/mcp/render.ts +110 -0
- package/src/mcp/schema.test.ts +86 -0
- package/src/mcp/schema.ts +93 -0
- package/src/mcp/server.test.ts +309 -0
- package/src/mcp/server.ts +276 -0
- package/src/scaffold/index.ts +102 -0
- package/src/scaffold/template-base/README.md +134 -0
- package/src/scaffold/template-base/_gitignore +4 -0
- package/src/scaffold/template-base/package.json +35 -0
- package/src/scaffold/template-base/src/components/Cover.tsx +30 -0
- package/src/scaffold/template-base/src/index.ts +27 -0
- package/src/scaffold/template-base/src/preview.tsx +9 -0
- package/src/scaffold/template-base/tsconfig.build.json +10 -0
- package/src/scaffold/template-base/tsconfig.json +18 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `slidesctl` — the CLI bin shipped with `@sanity-labs/slides`.
|
|
4
|
+
*
|
|
5
|
+
* Subcommands:
|
|
6
|
+
*
|
|
7
|
+
* serve --template <path-or-specifier> [--output <dir>] [--name <id>]
|
|
8
|
+
* Start an MCP server over stdio. Exposes `slides_list`,
|
|
9
|
+
* `slides_add_<type>`, and `slides_create` derived from the
|
|
10
|
+
* loaded template.
|
|
11
|
+
*
|
|
12
|
+
* generate --template <path-or-specifier> [--output <dir>]
|
|
13
|
+
* Read `{ title, slides: [...] }` JSON from stdin and write
|
|
14
|
+
* the resulting `.pptx`. Prints the absolute path on stdout.
|
|
15
|
+
*
|
|
16
|
+
* list --template <path-or-specifier>
|
|
17
|
+
* Print every slide type the template exposes, with
|
|
18
|
+
* descriptions. Useful for humans inspecting a template
|
|
19
|
+
* without an MCP client.
|
|
20
|
+
*
|
|
21
|
+
* scaffold <dir> [--name <slug>]
|
|
22
|
+
* Scaffold a new template into <dir>. Replaces the old
|
|
23
|
+
* `npm create react-pptx-template` flow.
|
|
24
|
+
*
|
|
25
|
+
* skill [--path]
|
|
26
|
+
* Print the bundled `SKILL.md` to stdout (or its absolute
|
|
27
|
+
* path with `--path`). Paste into a Claude project to teach
|
|
28
|
+
* the model how to drive any react-pptx MCP server.
|
|
29
|
+
*
|
|
30
|
+
* The `--template` flag accepts:
|
|
31
|
+
* - A bare package specifier resolved from the current directory
|
|
32
|
+
* (e.g. `@acme/slide-template`).
|
|
33
|
+
* - A path to a built JS file (`./dist/index.js`).
|
|
34
|
+
* - A path to a directory containing `package.json` (the bin reads
|
|
35
|
+
* `main` / `exports['.']`).
|
|
36
|
+
*/
|
|
37
|
+
import { readFileSync, realpathSync, statSync } from 'node:fs';
|
|
38
|
+
import { dirname, resolve as resolvePath } from 'node:path';
|
|
39
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
40
|
+
import { PptxSlidesRuntime } from './core/index.js';
|
|
41
|
+
import { renderSlides } from './mcp/render.js';
|
|
42
|
+
import { createSlideServer } from './mcp/server.js';
|
|
43
|
+
import { defaultName, scaffoldTemplate, validateName } from './scaffold/index.js';
|
|
44
|
+
const USAGE = `Usage: slidesctl <command> [options]
|
|
45
|
+
|
|
46
|
+
Commands:
|
|
47
|
+
serve Start an MCP server over stdio.
|
|
48
|
+
generate Read { title, slides } JSON from stdin, write a .pptx file.
|
|
49
|
+
list Print the slide types a template exposes.
|
|
50
|
+
scaffold Scaffold a new template into <dir>.
|
|
51
|
+
skill Print the bundled SKILL.md.
|
|
52
|
+
|
|
53
|
+
Options (serve / generate / list):
|
|
54
|
+
--template, -t <path> Template to load. Accepts a package name, a file
|
|
55
|
+
path, or a directory.
|
|
56
|
+
--output, -o <dir> Output directory for generated .pptx files
|
|
57
|
+
(serve/generate only; defaults to cwd).
|
|
58
|
+
--name, <id> MCP server name override (serve only).
|
|
59
|
+
|
|
60
|
+
Options (scaffold):
|
|
61
|
+
--name <slug> Template name (default: inferred from <dir>).
|
|
62
|
+
|
|
63
|
+
Options (skill):
|
|
64
|
+
--path Print SKILL.md's absolute path only.
|
|
65
|
+
|
|
66
|
+
Global:
|
|
67
|
+
--help, -h Show this message.
|
|
68
|
+
`;
|
|
69
|
+
const parseArgs = (argv) => {
|
|
70
|
+
const args = {
|
|
71
|
+
command: undefined,
|
|
72
|
+
positional: [],
|
|
73
|
+
template: undefined,
|
|
74
|
+
output: undefined,
|
|
75
|
+
name: undefined,
|
|
76
|
+
path: false,
|
|
77
|
+
help: false,
|
|
78
|
+
};
|
|
79
|
+
for (let i = 0; i < argv.length; i++) {
|
|
80
|
+
const arg = argv[i];
|
|
81
|
+
switch (arg) {
|
|
82
|
+
case '--help':
|
|
83
|
+
case '-h':
|
|
84
|
+
args.help = true;
|
|
85
|
+
break;
|
|
86
|
+
case '--template':
|
|
87
|
+
case '-t':
|
|
88
|
+
args.template = argv[++i];
|
|
89
|
+
break;
|
|
90
|
+
case '--output':
|
|
91
|
+
case '-o':
|
|
92
|
+
args.output = argv[++i];
|
|
93
|
+
break;
|
|
94
|
+
case '--name':
|
|
95
|
+
args.name = argv[++i];
|
|
96
|
+
break;
|
|
97
|
+
case '--path':
|
|
98
|
+
args.path = true;
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
if (arg === undefined)
|
|
102
|
+
break;
|
|
103
|
+
if (arg.startsWith('-'))
|
|
104
|
+
throw new CliError(`Unknown flag: ${arg}`);
|
|
105
|
+
if (args.command === undefined) {
|
|
106
|
+
args.command = arg;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
args.positional.push(arg);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return args;
|
|
114
|
+
};
|
|
115
|
+
class CliError extends Error {
|
|
116
|
+
exitCode;
|
|
117
|
+
constructor(message, exitCode = 2) {
|
|
118
|
+
super(message);
|
|
119
|
+
this.exitCode = exitCode;
|
|
120
|
+
this.name = 'CliError';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Resolve a `--template` argument to a Template instance.
|
|
125
|
+
*
|
|
126
|
+
* The template is the default export of the resolved module, or any named
|
|
127
|
+
* export that matches the Template shape (`name`, `components`, `canvas`).
|
|
128
|
+
*/
|
|
129
|
+
const loadTemplate = async (spec) => {
|
|
130
|
+
const cwd = process.cwd();
|
|
131
|
+
let importTarget;
|
|
132
|
+
if (isAbsoluteOrRelative(spec)) {
|
|
133
|
+
const abs = resolvePath(cwd, spec);
|
|
134
|
+
let resolved;
|
|
135
|
+
try {
|
|
136
|
+
const stat = statSync(abs);
|
|
137
|
+
resolved = stat.isDirectory() ? resolveDirEntry(abs) : abs;
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
throw new CliError(`Cannot read --template path "${spec}" (resolved to "${abs}"): ${describeError(err)}`);
|
|
141
|
+
}
|
|
142
|
+
importTarget = pathToFileURL(resolved).href;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
importTarget = resolveBareSpecifier(spec, cwd);
|
|
146
|
+
}
|
|
147
|
+
let mod;
|
|
148
|
+
try {
|
|
149
|
+
mod = await import(importTarget);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
throw new CliError(`Failed to import template "${spec}": ${describeError(err)}`);
|
|
153
|
+
}
|
|
154
|
+
const template = pickTemplate(mod);
|
|
155
|
+
if (!template) {
|
|
156
|
+
throw new CliError(`Module at "${spec}" does not export a Template (need an object with name + components).`);
|
|
157
|
+
}
|
|
158
|
+
return template;
|
|
159
|
+
};
|
|
160
|
+
const isAbsoluteOrRelative = (spec) => spec.startsWith('.') || spec.startsWith('/') || /^[A-Z]:\\/i.test(spec);
|
|
161
|
+
const resolveDirEntry = (dir) => {
|
|
162
|
+
const pkgPath = resolvePath(dir, 'package.json');
|
|
163
|
+
let pkg;
|
|
164
|
+
try {
|
|
165
|
+
pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
throw new CliError(`Template directory "${dir}" has no readable package.json: ${describeError(err)}`);
|
|
169
|
+
}
|
|
170
|
+
const entry = pkg.module ?? pkg.main ?? exportsDefault(pkg.exports);
|
|
171
|
+
if (!entry) {
|
|
172
|
+
throw new CliError(`Template directory "${dir}" has no main/module/exports entry to import.`);
|
|
173
|
+
}
|
|
174
|
+
return resolvePath(dir, entry);
|
|
175
|
+
};
|
|
176
|
+
const exportsDefault = (exportsField) => {
|
|
177
|
+
if (typeof exportsField === 'string')
|
|
178
|
+
return exportsField;
|
|
179
|
+
if (exportsField && typeof exportsField === 'object') {
|
|
180
|
+
const dot = exportsField['.'];
|
|
181
|
+
if (typeof dot === 'string')
|
|
182
|
+
return dot;
|
|
183
|
+
if (dot && typeof dot === 'object') {
|
|
184
|
+
const sub = dot;
|
|
185
|
+
const candidate = sub['import'] ?? sub['default'] ?? sub['node'];
|
|
186
|
+
if (typeof candidate === 'string')
|
|
187
|
+
return candidate;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return undefined;
|
|
191
|
+
};
|
|
192
|
+
const resolveBareSpecifier = (spec, cwd) => {
|
|
193
|
+
// ESM resolution honours `exports.import` and other conditions that
|
|
194
|
+
// require.resolve() doesn't, which matters for templates that ship
|
|
195
|
+
// conditional exports. Anchor resolution at the user's cwd via a synthetic
|
|
196
|
+
// package.json URL so we look in their node_modules.
|
|
197
|
+
const parentUrl = pathToFileURL(resolvePath(cwd, 'package.json')).href;
|
|
198
|
+
try {
|
|
199
|
+
return import.meta.resolve(spec, parentUrl);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
throw new CliError(`Cannot resolve template "${spec}" from ${cwd}: ${describeError(err)}. ` +
|
|
203
|
+
`Install it as a dependency or pass a path with --template.`);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
const pickTemplate = (mod) => {
|
|
207
|
+
if (!mod || typeof mod !== 'object')
|
|
208
|
+
return undefined;
|
|
209
|
+
const candidates = [];
|
|
210
|
+
const m = mod;
|
|
211
|
+
if (m['default'])
|
|
212
|
+
candidates.push(m['default']);
|
|
213
|
+
for (const [key, value] of Object.entries(m)) {
|
|
214
|
+
if (key === 'default')
|
|
215
|
+
continue;
|
|
216
|
+
candidates.push(value);
|
|
217
|
+
}
|
|
218
|
+
for (const c of candidates) {
|
|
219
|
+
if (isTemplate(c))
|
|
220
|
+
return c;
|
|
221
|
+
}
|
|
222
|
+
return undefined;
|
|
223
|
+
};
|
|
224
|
+
const isTemplate = (value) => {
|
|
225
|
+
if (!value || typeof value !== 'object')
|
|
226
|
+
return false;
|
|
227
|
+
const v = value;
|
|
228
|
+
return typeof v['name'] === 'string' && typeof v['components'] === 'object';
|
|
229
|
+
};
|
|
230
|
+
const newRuntime = (output) => new PptxSlidesRuntime({ outputDir: output ?? process.cwd() });
|
|
231
|
+
const runServe = async (args) => {
|
|
232
|
+
if (!args.template)
|
|
233
|
+
throw new CliError('serve requires --template <path-or-specifier>.');
|
|
234
|
+
const template = await loadTemplate(args.template);
|
|
235
|
+
const runtime = newRuntime(args.output);
|
|
236
|
+
const server = createSlideServer({
|
|
237
|
+
template,
|
|
238
|
+
runtime,
|
|
239
|
+
...(args.name ? { serverInfo: { name: args.name, version: '0.1.0' } } : {}),
|
|
240
|
+
});
|
|
241
|
+
await server.start({ transport: 'stdio' });
|
|
242
|
+
};
|
|
243
|
+
const runList = async (args) => {
|
|
244
|
+
if (!args.template)
|
|
245
|
+
throw new CliError('list requires --template <path-or-specifier>.');
|
|
246
|
+
const template = await loadTemplate(args.template);
|
|
247
|
+
const lines = [`Template: ${template.name}`, '', 'Slide types:'];
|
|
248
|
+
for (const [name, tc] of Object.entries(template.components)) {
|
|
249
|
+
lines.push(` • ${name} — ${tc.description ?? '(no description)'}`);
|
|
250
|
+
}
|
|
251
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
252
|
+
};
|
|
253
|
+
const runGenerate = async (args) => {
|
|
254
|
+
if (!args.template)
|
|
255
|
+
throw new CliError('generate requires --template <path-or-specifier>.');
|
|
256
|
+
const template = await loadTemplate(args.template);
|
|
257
|
+
const runtime = newRuntime(args.output);
|
|
258
|
+
const raw = await readStdin();
|
|
259
|
+
if (raw.trim().length === 0) {
|
|
260
|
+
throw new CliError('generate: no input on stdin. Pipe JSON of { title, slides: [{ component, props }] }.');
|
|
261
|
+
}
|
|
262
|
+
let input;
|
|
263
|
+
try {
|
|
264
|
+
input = JSON.parse(raw);
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
throw new CliError(`generate: invalid JSON on stdin: ${describeError(err)}`);
|
|
268
|
+
}
|
|
269
|
+
if (typeof input.title !== 'string' || !Array.isArray(input.slides)) {
|
|
270
|
+
throw new CliError('generate: input must be { title: string, slides: array }.');
|
|
271
|
+
}
|
|
272
|
+
const result = await renderSlides({
|
|
273
|
+
template,
|
|
274
|
+
runtime,
|
|
275
|
+
title: input.title,
|
|
276
|
+
slides: input.slides,
|
|
277
|
+
});
|
|
278
|
+
if (result.ok) {
|
|
279
|
+
process.stdout.write(`${result.filePath}\n`);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
throw new CliError(result.message, result.code === 'unknown_component' ? 3 : 2);
|
|
283
|
+
};
|
|
284
|
+
const runSkill = (args) => {
|
|
285
|
+
const skillPath = resolveSkillPath();
|
|
286
|
+
if (args.path) {
|
|
287
|
+
process.stdout.write(`${skillPath}\n`);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
process.stdout.write(readFileSync(skillPath, 'utf8'));
|
|
291
|
+
};
|
|
292
|
+
const runScaffold = (args) => {
|
|
293
|
+
const [target] = args.positional;
|
|
294
|
+
if (!target) {
|
|
295
|
+
throw new CliError('scaffold requires a target directory: `slidesctl scaffold my-template`.');
|
|
296
|
+
}
|
|
297
|
+
const name = args.name ?? defaultName(target);
|
|
298
|
+
const nameError = validateName(name);
|
|
299
|
+
if (nameError) {
|
|
300
|
+
throw new CliError(`Invalid template name "${name}": ${nameError}. ` + `Pass --name <slug> with a valid name.`);
|
|
301
|
+
}
|
|
302
|
+
const result = scaffoldTemplate({ target, name });
|
|
303
|
+
process.stdout.write(`Scaffolded ${result.fileCount} files into ${result.targetPath}\n`);
|
|
304
|
+
process.stdout.write(`\nNext steps:\n cd ${target}\n pnpm install\n pnpm dev # open the viewer\n pnpm build # emit dist/ so slidesctl can serve it\n`);
|
|
305
|
+
};
|
|
306
|
+
const resolveSkillPath = () => {
|
|
307
|
+
// SKILL.md ships at the package root, one level above dist/cli.js.
|
|
308
|
+
// From src/cli.ts the same relative path resolves correctly because
|
|
309
|
+
// we run from dist/ in production.
|
|
310
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
311
|
+
return resolvePath(here, '..', 'SKILL.md');
|
|
312
|
+
};
|
|
313
|
+
const readStdin = () => {
|
|
314
|
+
const chunks = [];
|
|
315
|
+
return new Promise((resolve, reject) => {
|
|
316
|
+
process.stdin.on('data', (chunk) => {
|
|
317
|
+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : chunk);
|
|
318
|
+
});
|
|
319
|
+
process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
320
|
+
process.stdin.on('error', (err) => reject(err));
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
const describeError = (err) => (err instanceof Error ? err.message : String(err));
|
|
324
|
+
export const main = async (argv) => {
|
|
325
|
+
let args;
|
|
326
|
+
try {
|
|
327
|
+
args = parseArgs(argv);
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
331
|
+
process.stderr.write(USAGE);
|
|
332
|
+
process.exit(2);
|
|
333
|
+
}
|
|
334
|
+
if (args.help || args.command === undefined) {
|
|
335
|
+
process.stdout.write(USAGE);
|
|
336
|
+
process.exit(args.help ? 0 : 1);
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
switch (args.command) {
|
|
340
|
+
case 'serve':
|
|
341
|
+
await runServe(args);
|
|
342
|
+
return;
|
|
343
|
+
case 'list':
|
|
344
|
+
await runList(args);
|
|
345
|
+
return;
|
|
346
|
+
case 'generate':
|
|
347
|
+
await runGenerate(args);
|
|
348
|
+
return;
|
|
349
|
+
case 'scaffold':
|
|
350
|
+
runScaffold(args);
|
|
351
|
+
return;
|
|
352
|
+
case 'skill':
|
|
353
|
+
runSkill(args);
|
|
354
|
+
return;
|
|
355
|
+
default:
|
|
356
|
+
process.stderr.write(`Unknown command: ${args.command}\n`);
|
|
357
|
+
process.stderr.write(USAGE);
|
|
358
|
+
process.exit(2);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
if (err instanceof CliError) {
|
|
363
|
+
process.stderr.write(`${err.message}\n`);
|
|
364
|
+
process.exit(err.exitCode);
|
|
365
|
+
}
|
|
366
|
+
process.stderr.write(`slidesctl failed: ${describeError(err)}\n`);
|
|
367
|
+
process.exit(1);
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
// pnpm's content-addressed install layout means `process.argv[1]` is the
|
|
371
|
+
// `.bin` symlink while `import.meta.url` is the realpath under `.pnpm/`.
|
|
372
|
+
// Use realpathSync on both sides so direct invocation and
|
|
373
|
+
// `node_modules/.bin/slidesctl` both detect this file as the entrypoint.
|
|
374
|
+
const argvPath = process.argv[1];
|
|
375
|
+
if (argvPath !== undefined) {
|
|
376
|
+
try {
|
|
377
|
+
const argvReal = realpathSync(argvPath);
|
|
378
|
+
const selfReal = fileURLToPath(import.meta.url);
|
|
379
|
+
if (argvReal === selfReal)
|
|
380
|
+
void main(process.argv.slice(2));
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
// not invoked as a script — module being imported, ignore.
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The minimal JSX primitive surface the reconciler walks.
|
|
3
|
+
*
|
|
4
|
+
* **This is intentionally a small, lower-case set.** High-level brand
|
|
5
|
+
* components (`<Cover/>`, `<TwoColumn/>`, etc.) live in brand packages
|
|
6
|
+
* (e.g., `@sanity-labs/slides`) and *compose* these primitives. The substrate
|
|
7
|
+
* exports just enough to render an arbitrary slide tree.
|
|
8
|
+
*
|
|
9
|
+
* Why hand-rolled host elements rather than `<div>`-style intrinsic elements:
|
|
10
|
+
* we want the reconciler to recognize these by *type identity*, not by string
|
|
11
|
+
* tag names. Type identity removes a class of bugs ("did you mean 'box' or
|
|
12
|
+
* 'Box'?") and gives the type-checker something concrete to enforce.
|
|
13
|
+
*
|
|
14
|
+
* These don't render to the DOM — they're inert markers the reconciler walks.
|
|
15
|
+
* They return `null` so they're harmless if accidentally rendered through
|
|
16
|
+
* react-dom (e.g., during Storybook prototyping).
|
|
17
|
+
*/
|
|
18
|
+
import type { ReactNode } from 'react';
|
|
19
|
+
import type { Rect } from './geometry.js';
|
|
20
|
+
import type { ArtifactRef, SlotId } from './manifest.js';
|
|
21
|
+
import type { HexColor, ParagraphStyle, TextStyle } from './runtime.js';
|
|
22
|
+
/**
|
|
23
|
+
* A single slide in the deck.
|
|
24
|
+
*
|
|
25
|
+
* Every `<Slide>` becomes a `createSlide` op. Children are rendered into the
|
|
26
|
+
* slide's coordinate space.
|
|
27
|
+
*/
|
|
28
|
+
export interface SlideProps {
|
|
29
|
+
/** Children: `<Box>` and `<Image>` shapes laid out inside the slide. */
|
|
30
|
+
children?: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A discriminated union describing a `<Box>`'s background fill.
|
|
34
|
+
*
|
|
35
|
+
* Shaped as a tagged union — *not* a flat `fill?: HexColor` — so future fill
|
|
36
|
+
* kinds (texture, image-as-background, gradient) can be added without
|
|
37
|
+
* sprouting parallel optional props. The discriminator is load-bearing:
|
|
38
|
+
* off-brand fills are inexpressible at the type level when a brand component
|
|
39
|
+
* narrows what kinds it accepts.
|
|
40
|
+
*
|
|
41
|
+
* Today only `'solid'` is supported. Image fills (full-bleed photos) are
|
|
42
|
+
* authored as `<Image>` siblings of `<Box>` rather than nested inside a
|
|
43
|
+
* Box's fill.
|
|
44
|
+
*/
|
|
45
|
+
export type BoxFill = {
|
|
46
|
+
kind: 'solid';
|
|
47
|
+
color: HexColor;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* A rectangular text box on the slide canvas.
|
|
51
|
+
*
|
|
52
|
+
* Becomes a `createShape` op with shape `TEXT_BOX` (the only shape this
|
|
53
|
+
* primitive set produces; other shape kinds are reserved for the future).
|
|
54
|
+
* Children are concatenated into a single text run with style spans.
|
|
55
|
+
*/
|
|
56
|
+
export interface BoxProps {
|
|
57
|
+
/** The shape's rect in *points*. The reconciler converts to EMU at the boundary. */
|
|
58
|
+
rect: Rect;
|
|
59
|
+
/**
|
|
60
|
+
* Optional slot ID, encoded into the shape's alt-text. Required for any text
|
|
61
|
+
* box that re-fill should target. Format: `<componentName>:<slotName>`,
|
|
62
|
+
* e.g., `"cover:title"`. See `manifest.ts` for encoding details.
|
|
63
|
+
*/
|
|
64
|
+
slotId?: SlotId;
|
|
65
|
+
/**
|
|
66
|
+
* Optional background fill. When set, the reconciler emits an
|
|
67
|
+
* `updateShapeProperties` op immediately after the shape is created,
|
|
68
|
+
* before any text or text-style ops. An empty Box (no children) with a
|
|
69
|
+
* `fill` is a valid full-bleed colored background.
|
|
70
|
+
*/
|
|
71
|
+
fill?: BoxFill;
|
|
72
|
+
/** Default text style applied to the shape's contents. */
|
|
73
|
+
textStyle?: TextStyle;
|
|
74
|
+
/** Default paragraph style. */
|
|
75
|
+
paragraphStyle?: ParagraphStyle;
|
|
76
|
+
/** Children: `<Text>` runs and/or raw strings. */
|
|
77
|
+
children?: ReactNode;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A styled text run inside a `<Box>`.
|
|
81
|
+
*
|
|
82
|
+
* Multiple `<Text>` children of the same `<Box>` are concatenated; each
|
|
83
|
+
* run's style is applied to its character range via `updateTextStyle` ops.
|
|
84
|
+
* Raw string children of `<Box>` are equivalent to `<Text>{text}</Text>`
|
|
85
|
+
* with no style override.
|
|
86
|
+
*
|
|
87
|
+
* The intent of carrying `textStyle` here (rather than mandating a typography
|
|
88
|
+
* token) is: high-level brand components compose this primitive *and* enforce
|
|
89
|
+
* brand-token discipline at *their* layer. The substrate stays brand-agnostic.
|
|
90
|
+
*/
|
|
91
|
+
export interface TextProps {
|
|
92
|
+
/** Style applied to this run only. Merges over `<Box>`'s `textStyle`. */
|
|
93
|
+
textStyle?: TextStyle;
|
|
94
|
+
/** Children: text content. Nested elements are flattened to their text. */
|
|
95
|
+
children?: ReactNode;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A wrapper that sets the foreground color of its children.
|
|
99
|
+
*
|
|
100
|
+
* A thin convenience over `<Text textStyle={{foregroundColor}}/>` so
|
|
101
|
+
* brand components can read more declaratively. The reconciler treats this
|
|
102
|
+
* identically to a `<Text>` with the same style.
|
|
103
|
+
*/
|
|
104
|
+
export interface ColorProps {
|
|
105
|
+
/** The color to apply, as a 24-bit hex. (`#RRGGBB`.) */
|
|
106
|
+
color: HexColor;
|
|
107
|
+
/** Children: text or `<Text>` runs. */
|
|
108
|
+
children?: ReactNode;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A reference to a brand-resolved image, including its provenance.
|
|
112
|
+
*
|
|
113
|
+
* The `artifact` field is **required**: every image rendered through the
|
|
114
|
+
* substrate is recorded in the generation manifest's `artifacts` list, so
|
|
115
|
+
* downstream tooling can detect 404s and verify content integrity. An
|
|
116
|
+
* `<Image>` without a `ArtifactRef` is impossible to construct —
|
|
117
|
+
* type-level enforcement of the manifest contract.
|
|
118
|
+
*/
|
|
119
|
+
export interface ImageRef {
|
|
120
|
+
/** Resolved URL the runtime will fetch the image bytes from. */
|
|
121
|
+
readonly url: string;
|
|
122
|
+
/** Template-artifact provenance — recorded in manifest.artifacts. Required. */
|
|
123
|
+
readonly artifact: ArtifactRef;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* A bitmap image placed on a slide, rendered as a `createImage` op.
|
|
127
|
+
*
|
|
128
|
+
* Sibling of `<Box>` inside a `<Slide>`. Used for full-bleed background
|
|
129
|
+
* photos, dot-grid texture overlays, brand logos, and any other rasterized
|
|
130
|
+
* brand artifact. Vector content (lines, rectangles, etc.) goes through
|
|
131
|
+
* `<Box>` and the (future) shape-kind extension to its fill prop.
|
|
132
|
+
*/
|
|
133
|
+
export interface ImageProps {
|
|
134
|
+
/** The image's rect in *points*. The reconciler converts to EMU at the boundary. */
|
|
135
|
+
rect: Rect;
|
|
136
|
+
/**
|
|
137
|
+
* The image to render, including its brand-artifact provenance. Required —
|
|
138
|
+
* an `<Image>` without an `ImageRef` is unconstructable, by design.
|
|
139
|
+
*/
|
|
140
|
+
image: ImageRef;
|
|
141
|
+
/**
|
|
142
|
+
* Optional slot ID. When set, the reconciler records `SlotId → imageId` in
|
|
143
|
+
* the manifest's slot registry.
|
|
144
|
+
*/
|
|
145
|
+
slotId?: SlotId;
|
|
146
|
+
/**
|
|
147
|
+
* Accessibility alt-text shown to assistive tech.
|
|
148
|
+
*
|
|
149
|
+
* Carried through to the `createImage` op's `altText` field.
|
|
150
|
+
*/
|
|
151
|
+
altText?: string;
|
|
152
|
+
}
|
|
153
|
+
/** A unique brand for each primitive's React component. */
|
|
154
|
+
type Marker<TProps> = ((props: TProps) => null) & {
|
|
155
|
+
readonly __rgsKind: string;
|
|
156
|
+
};
|
|
157
|
+
export declare const Slide: Marker<SlideProps>;
|
|
158
|
+
export declare const Box: Marker<BoxProps>;
|
|
159
|
+
export declare const Text: Marker<TextProps>;
|
|
160
|
+
export declare const Color: Marker<ColorProps>;
|
|
161
|
+
export declare const Image: Marker<ImageProps>;
|
|
162
|
+
/**
|
|
163
|
+
* The set of primitive React components the reconciler recognizes.
|
|
164
|
+
*
|
|
165
|
+
* Used internally for type identity checks (see `reconciler.ts`). Exposed for
|
|
166
|
+
* downstream packages that want to detect "is this a substrate primitive?"
|
|
167
|
+
* without importing each one individually.
|
|
168
|
+
*/
|
|
169
|
+
export declare const PRIMITIVES: {
|
|
170
|
+
readonly Slide: Marker<SlideProps>;
|
|
171
|
+
readonly Box: Marker<BoxProps>;
|
|
172
|
+
readonly Text: Marker<TextProps>;
|
|
173
|
+
readonly Color: Marker<ColorProps>;
|
|
174
|
+
readonly Image: Marker<ImageProps>;
|
|
175
|
+
};
|
|
176
|
+
/** Type guard: is this React element type one of our primitives? */
|
|
177
|
+
export declare const isPrimitive: (type: unknown) => type is (typeof PRIMITIVES)[keyof typeof PRIMITIVES];
|
|
178
|
+
export {};
|
|
179
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/core/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAExE;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,oFAAoF;IACpF,IAAI,EAAE,IAAI,CAAC;IAEX;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,0DAA0D;IAC1D,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC,kDAAkD;IAClD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,yEAAyE;IACzE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,KAAK,EAAE,QAAQ,CAAC;IAChB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ;IACvB,gEAAgE;IAChE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,oFAAoF;IACpF,IAAI,EAAE,IAAI,CAAC;IAEX;;;OAGG;IACH,KAAK,EAAE,QAAQ,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,2DAA2D;AAC3D,KAAK,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AASjF,eAAO,MAAM,KAAK,oBAAkC,CAAC;AACrD,eAAO,MAAM,GAAG,kBAA8B,CAAC;AAC/C,eAAO,MAAM,IAAI,mBAAgC,CAAC;AAClD,eAAO,MAAM,KAAK,oBAAkC,CAAC;AACrD,eAAO,MAAM,KAAK,oBAAkC,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU;;;;;;CAA8C,CAAC;AAItE,oEAAoE;AACpE,eAAO,MAAM,WAAW,GAAI,MAAM,OAAO,KAAG,IAAI,IAAI,CAAC,OAAO,UAAU,EAAE,MAAM,OAAO,UAAU,CACtE,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The minimal JSX primitive surface the reconciler walks.
|
|
3
|
+
*
|
|
4
|
+
* **This is intentionally a small, lower-case set.** High-level brand
|
|
5
|
+
* components (`<Cover/>`, `<TwoColumn/>`, etc.) live in brand packages
|
|
6
|
+
* (e.g., `@sanity-labs/slides`) and *compose* these primitives. The substrate
|
|
7
|
+
* exports just enough to render an arbitrary slide tree.
|
|
8
|
+
*
|
|
9
|
+
* Why hand-rolled host elements rather than `<div>`-style intrinsic elements:
|
|
10
|
+
* we want the reconciler to recognize these by *type identity*, not by string
|
|
11
|
+
* tag names. Type identity removes a class of bugs ("did you mean 'box' or
|
|
12
|
+
* 'Box'?") and gives the type-checker something concrete to enforce.
|
|
13
|
+
*
|
|
14
|
+
* These don't render to the DOM — they're inert markers the reconciler walks.
|
|
15
|
+
* They return `null` so they're harmless if accidentally rendered through
|
|
16
|
+
* react-dom (e.g., during Storybook prototyping).
|
|
17
|
+
*/
|
|
18
|
+
const makeMarker = (kind) => {
|
|
19
|
+
const component = (_props) => null;
|
|
20
|
+
// Display name aids debugging in React DevTools and assertion messages.
|
|
21
|
+
Object.defineProperty(component, 'name', { value: kind });
|
|
22
|
+
return Object.assign(component, { __rgsKind: kind });
|
|
23
|
+
};
|
|
24
|
+
export const Slide = makeMarker('Slide');
|
|
25
|
+
export const Box = makeMarker('Box');
|
|
26
|
+
export const Text = makeMarker('Text');
|
|
27
|
+
export const Color = makeMarker('Color');
|
|
28
|
+
export const Image = makeMarker('Image');
|
|
29
|
+
/**
|
|
30
|
+
* The set of primitive React components the reconciler recognizes.
|
|
31
|
+
*
|
|
32
|
+
* Used internally for type identity checks (see `reconciler.ts`). Exposed for
|
|
33
|
+
* downstream packages that want to detect "is this a substrate primitive?"
|
|
34
|
+
* without importing each one individually.
|
|
35
|
+
*/
|
|
36
|
+
export const PRIMITIVES = { Slide, Box, Text, Color, Image };
|
|
37
|
+
const PRIMITIVE_SET = new Set(Object.values(PRIMITIVES));
|
|
38
|
+
/** Type guard: is this React element type one of our primitives? */
|
|
39
|
+
export const isPrimitive = (type) => PRIMITIVE_SET.has(type);
|
|
40
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../../src/core/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAyJH,MAAM,UAAU,GAAG,CAAS,IAAY,EAAkB,EAAE;IAC1D,MAAM,SAAS,GAAG,CAAC,MAAc,EAAQ,EAAE,CAAC,IAAI,CAAC;IACjD,wEAAwE;IACxE,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAW,CAAC,CAAC;AAChE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAa,OAAO,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,GAAG,GAAG,UAAU,CAAW,KAAK,CAAC,CAAC;AAC/C,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAY,MAAM,CAAC,CAAC;AAClD,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAa,OAAO,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAa,OAAO,CAAC,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAW,CAAC;AAEtE,MAAM,aAAa,GAAG,IAAI,GAAG,CAAU,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAElE,oEAAoE;AACpE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAa,EAAwD,EAAE,CACjG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC"}
|