rip-lang 3.15.4 → 3.16.1
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 +6 -4
- package/bin/rip +167 -12
- package/docs/AGENTS.md +1 -1
- package/docs/RIP-APP.md +808 -0
- package/docs/RIP-DUCKDB.md +477 -0
- package/docs/RIP-INTRO.md +396 -0
- package/docs/RIP-LANG.md +59 -5
- package/docs/RIP-SCHEMA.md +191 -8
- package/docs/RIP-TYPES.md +74 -103
- package/docs/demo/README.md +4 -3
- package/docs/dist/rip.js +3627 -1470
- package/docs/dist/rip.min.js +671 -244
- package/docs/dist/rip.min.js.br +0 -0
- package/docs/example/index.json +7 -7
- package/docs/example/index.json.br +0 -0
- package/docs/extensions/duckdb/manifest.json +1 -1
- package/docs/extensions/duckdb/v1.5.2/linux_amd64/ripdb.duckdb_extension.gz +0 -0
- package/docs/extensions/duckdb/v1.5.2/osx_arm64/ripdb.duckdb_extension.gz +0 -0
- package/docs/extensions/vscode/print/index.html +2 -1
- package/docs/extensions/vscode/print/print-1.0.13.vsix +0 -0
- package/docs/extensions/vscode/print/print-1.0.14.vsix +0 -0
- package/docs/extensions/vscode/print/print-latest.vsix +0 -0
- package/docs/extensions/vscode/rip/rip-0.5.15.vsix +0 -0
- package/docs/extensions/vscode/rip/rip-latest.vsix +0 -0
- package/docs/ui/bundle.json +61 -0
- package/docs/ui/bundle.json.br +0 -0
- package/docs/ui/hljs-rip.js +0 -7
- package/docs/ui/index.css +66 -23
- package/docs/ui/index.html +6 -6
- package/package.json +9 -3
- package/rip-loader.js +64 -2
- package/src/AGENTS.md +63 -36
- package/src/browser.js +96 -14
- package/src/compiler.js +960 -143
- package/src/components.js +794 -88
- package/src/{types-emit.js → dts.js} +181 -71
- package/src/grammar/README.md +1 -1
- package/src/grammar/grammar.rip +111 -97
- package/src/lexer.js +132 -18
- package/src/parser.js +203 -205
- package/src/repl.js +74 -6
- package/src/schema/runtime-orm.js +168 -4
- package/src/schema/runtime-validate.js +146 -2
- package/src/schema/runtime.generated.js +314 -6
- package/src/schema/schema.js +5 -5
- package/src/sourcemaps.js +277 -1
- package/src/stdlib.js +253 -0
- package/src/typecheck.js +2023 -106
- package/src/types.js +127 -7
- package/docs/ui/accordion.rip +0 -103
- package/docs/ui/alert-dialog.rip +0 -53
- package/docs/ui/autocomplete.rip +0 -115
- package/docs/ui/avatar.rip +0 -37
- package/docs/ui/badge.rip +0 -15
- package/docs/ui/breadcrumb.rip +0 -47
- package/docs/ui/button-group.rip +0 -26
- package/docs/ui/button.rip +0 -23
- package/docs/ui/card.rip +0 -25
- package/docs/ui/carousel.rip +0 -110
- package/docs/ui/checkbox-group.rip +0 -61
- package/docs/ui/checkbox.rip +0 -33
- package/docs/ui/collapsible.rip +0 -50
- package/docs/ui/combobox.rip +0 -130
- package/docs/ui/context-menu.rip +0 -88
- package/docs/ui/date-picker.rip +0 -206
- package/docs/ui/dialog.rip +0 -60
- package/docs/ui/drawer.rip +0 -58
- package/docs/ui/editable-value.rip +0 -82
- package/docs/ui/field.rip +0 -53
- package/docs/ui/fieldset.rip +0 -22
- package/docs/ui/form.rip +0 -39
- package/docs/ui/grid.rip +0 -901
- package/docs/ui/input-group.rip +0 -28
- package/docs/ui/input.rip +0 -36
- package/docs/ui/label.rip +0 -16
- package/docs/ui/menu.rip +0 -134
- package/docs/ui/menubar.rip +0 -151
- package/docs/ui/meter.rip +0 -36
- package/docs/ui/multi-select.rip +0 -203
- package/docs/ui/native-select.rip +0 -33
- package/docs/ui/nav-menu.rip +0 -126
- package/docs/ui/number-field.rip +0 -162
- package/docs/ui/otp-field.rip +0 -89
- package/docs/ui/pagination.rip +0 -123
- package/docs/ui/popover.rip +0 -93
- package/docs/ui/preview-card.rip +0 -75
- package/docs/ui/progress.rip +0 -25
- package/docs/ui/radio-group.rip +0 -57
- package/docs/ui/resizable.rip +0 -123
- package/docs/ui/scroll-area.rip +0 -145
- package/docs/ui/select.rip +0 -151
- package/docs/ui/separator.rip +0 -17
- package/docs/ui/skeleton.rip +0 -22
- package/docs/ui/slider.rip +0 -165
- package/docs/ui/spinner.rip +0 -17
- package/docs/ui/table.rip +0 -27
- package/docs/ui/tabs.rip +0 -113
- package/docs/ui/textarea.rip +0 -48
- package/docs/ui/toast.rip +0 -87
- package/docs/ui/toggle-group.rip +0 -71
- package/docs/ui/toggle.rip +0 -24
- package/docs/ui/toolbar.rip +0 -38
- package/docs/ui/tooltip.rip +0 -85
- package/src/app.rip +0 -1571
- package/src/sourcemap-merge.js +0 -287
- /package/docs/demo/{components → routes}/_layout.rip +0 -0
- /package/docs/demo/{components → routes}/about.rip +0 -0
- /package/docs/demo/{components → routes}/card.rip +0 -0
- /package/docs/demo/{components → routes}/counter.rip +0 -0
- /package/docs/demo/{components → routes}/index.rip +0 -0
- /package/docs/demo/{components → routes}/todos.rip +0 -0
- /package/src/schema/{dts-emit.js → dts.js} +0 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<a href="https://github.com/shreeve/rip-lang/commits/main"><img src="https://img.shields.io/badge/version-3.
|
|
12
|
+
<a href="https://github.com/shreeve/rip-lang/commits/main"><img src="https://img.shields.io/badge/version-3.16.1-blue.svg" alt="Version"></a>
|
|
13
13
|
<a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
|
|
14
14
|
<a href="#"><img src="https://img.shields.io/badge/tests-1%2C436%2F1%2C436-brightgreen.svg" alt="Tests"></a>
|
|
15
15
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
|
|
@@ -414,13 +414,13 @@ That's it. All `<script type="text/rip">` tags share scope — `export` makes na
|
|
|
414
414
|
<script type="text/rip" src="app.rip"></script>
|
|
415
415
|
|
|
416
416
|
<!-- Bundle — fetch all components from a server endpoint -->
|
|
417
|
-
<script defer src="/rip/rip.min.js" data-src="
|
|
417
|
+
<script defer src="/rip/rip.min.js" data-src="app" data-mount="App"></script>
|
|
418
418
|
|
|
419
419
|
<!-- Bundle with stash persistence (sessionStorage) -->
|
|
420
|
-
<script defer src="/rip/rip.min.js" data-src="
|
|
420
|
+
<script defer src="/rip/rip.min.js" data-src="app" data-mount="App" data-persist></script>
|
|
421
421
|
|
|
422
422
|
<!-- Mix bundles and individual files -->
|
|
423
|
-
<script defer src="/rip/rip.min.js" data-src="/rip/ui
|
|
423
|
+
<script defer src="/rip/rip.min.js" data-src="/rip/ui app header.rip" data-mount="App"></script>
|
|
424
424
|
```
|
|
425
425
|
|
|
426
426
|
Every component has a static `mount(target)` method — `App.mount '#app'` is shorthand for `App.new().mount('#app')`. Target defaults to `'body'`.
|
|
@@ -561,6 +561,8 @@ bun run bump major
|
|
|
561
561
|
| [docs/RIP-LANG.md](docs/RIP-LANG.md) | Full language reference (syntax, operators, reactivity, types, components) |
|
|
562
562
|
| [docs/RIP-TYPES.md](docs/RIP-TYPES.md) | Type system specification |
|
|
563
563
|
| [docs/RIP-SCHEMA.md](docs/RIP-SCHEMA.md) | Schema keyword — validators, models, ORM, DDL, algebra |
|
|
564
|
+
| [docs/RIP-DUCKDB.md](docs/RIP-DUCKDB.md) | DuckDB foreign-key constraints — what works, what doesn't, how the ORM keeps you safe |
|
|
565
|
+
| [docs/RIP-APP.md](docs/RIP-APP.md) | Rip App — browser framework architecture, subsystems, lifecycle invariants, gotchas |
|
|
564
566
|
| [AGENTS.md](AGENTS.md) | AI agents — compiler architecture, subsystems, conventions |
|
|
565
567
|
|
|
566
568
|
---
|
package/bin/rip
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
import { readFileSync, readdirSync, writeFileSync, existsSync, statSync, unlinkSync } from 'fs';
|
|
3
|
+
import { readFileSync, readdirSync, writeFileSync, existsSync, statSync, unlinkSync, lstatSync, readlinkSync, rmSync, mkdirSync, symlinkSync, realpathSync } from 'fs';
|
|
4
4
|
import { execSync, spawnSync, spawn } from 'child_process';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { dirname, basename, join } from 'path';
|
|
@@ -8,7 +8,7 @@ import { Compiler, formatError } from '../src/compiler.js';
|
|
|
8
8
|
// Side-effect imports — register CLI-side runtime providers. The browser
|
|
9
9
|
// bundle imports a different schema loader so server-only fragments
|
|
10
10
|
// (db-naming/orm/ddl) tree-shake out of docs/dist/rip.min.js.
|
|
11
|
-
import '../src/
|
|
11
|
+
import '../src/dts.js'; // registers emitTypes for .d.ts output
|
|
12
12
|
import '../src/schema/loader-server.js'; // registers full schema runtime
|
|
13
13
|
import packageJson from '../package.json' with { type: 'json' };
|
|
14
14
|
|
|
@@ -60,7 +60,12 @@ Options:
|
|
|
60
60
|
|
|
61
61
|
Subcommands:
|
|
62
62
|
rip check [dir] Type-check all .rip files in directory
|
|
63
|
-
rip check --
|
|
63
|
+
rip check --audit [pkgDir] Audit a typed package's public API surface for 'any' leaks
|
|
64
|
+
rip check --sourcemap [dir] Verify source-map round-trip for every identifier
|
|
65
|
+
(hover/go-to-def integrity). Useful for compiler work.
|
|
66
|
+
rip link [--quiet] After 'bun install', symlink @rip-lang/* deps to
|
|
67
|
+
local source (opt-in, for framework devs;
|
|
68
|
+
undo with 'bun install --force')
|
|
64
69
|
rip <name> [args] Run rip-<name> (repo bin/, node_modules, or PATH)
|
|
65
70
|
|
|
66
71
|
Configure via rip.json or package.json:
|
|
@@ -95,6 +100,121 @@ Shebang support:
|
|
|
95
100
|
`);
|
|
96
101
|
}
|
|
97
102
|
|
|
103
|
+
// `rip link` — opt-in override for framework maintainers, layered on top of a
|
|
104
|
+
// normal install. The canonical setup for any rip project is `bun install`
|
|
105
|
+
// (published packages, lockfile, transitive deps); `rip link` then redirects
|
|
106
|
+
// the @rip-lang/* deps to this CLI's own source checkout, by symlinking them
|
|
107
|
+
// into ./node_modules/@rip-lang/* (plus matching .bin shims). The `rip-lang`
|
|
108
|
+
// compiler/toolchain is pointed at source too, so the loader and VS Code LSP
|
|
109
|
+
// load the matching toolchain instead of a shadowing published tarball. Lets
|
|
110
|
+
// you edit framework source live without publishing.
|
|
111
|
+
//
|
|
112
|
+
// Requires `bun install` first — it overrides an existing install, it is not a
|
|
113
|
+
// substitute for one. Reversible: the symlinks live in node_modules (gitignored)
|
|
114
|
+
// and package.json stays clean semver, so `bun install --force` restores the
|
|
115
|
+
// published packages (a plain `bun install` sees the lockfile as satisfied and
|
|
116
|
+
// leaves the symlinks in place). No-op when no source tree is found (e.g. `rip`
|
|
117
|
+
// installed from npm without a dev checkout) — projects then just use installed
|
|
118
|
+
// packages.
|
|
119
|
+
//
|
|
120
|
+
// Source is this CLI's repo root (so it Just Works after `link-global`),
|
|
121
|
+
// overridable via RIP_SRC.
|
|
122
|
+
function ripLink(args) {
|
|
123
|
+
const quiet = args.includes('--quiet');
|
|
124
|
+
const log = (msg) => { if (!quiet) console.log(`[rip] link: ${msg}`); };
|
|
125
|
+
|
|
126
|
+
const rawSrc = process.env.RIP_SRC || join(__dirname, '..');
|
|
127
|
+
if (!existsSync(join(rawSrc, 'packages'))) {
|
|
128
|
+
log(`no rip-lang source at ${rawSrc} — using installed packages (set RIP_SRC to override)`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const src = realpathSync(rawSrc);
|
|
132
|
+
|
|
133
|
+
const cwd = process.cwd();
|
|
134
|
+
const pkgPath = join(cwd, 'package.json');
|
|
135
|
+
if (!existsSync(pkgPath)) {
|
|
136
|
+
console.error('[rip] link: no package.json in current directory');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
140
|
+
const deps = Object.keys(pkg.dependencies || {}).filter((d) => d.startsWith('@rip-lang/'));
|
|
141
|
+
if (deps.length === 0) {
|
|
142
|
+
log('no @rip-lang/* dependencies declared — nothing to link');
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const nodeModules = join(cwd, 'node_modules');
|
|
147
|
+
if (!existsSync(nodeModules)) {
|
|
148
|
+
console.error('[rip] link: no node_modules found — run `bun install` first, then `rip link`.');
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
const binDir = join(nodeModules, '.bin');
|
|
152
|
+
|
|
153
|
+
const linkTo = (path, target, type = 'dir') => {
|
|
154
|
+
try {
|
|
155
|
+
if (lstatSync(path).isSymbolicLink() && readlinkSync(path) === target) return false;
|
|
156
|
+
rmSync(path, { recursive: true, force: true });
|
|
157
|
+
} catch {}
|
|
158
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
159
|
+
symlinkSync(target, path, type);
|
|
160
|
+
return true;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const linked = []; // { dep, bins: [names] } for each resolved package
|
|
164
|
+
let changed = false;
|
|
165
|
+
|
|
166
|
+
for (const dep of deps) {
|
|
167
|
+
const short = dep.slice('@rip-lang/'.length);
|
|
168
|
+
const target = join(src, 'packages', short);
|
|
169
|
+
if (!existsSync(target)) { log(`skip ${dep} — not found at ${target}`); continue; }
|
|
170
|
+
if (linkTo(join(nodeModules, '@rip-lang', short), target)) changed = true;
|
|
171
|
+
|
|
172
|
+
// Re-create .bin shims from the package's own `bin` field so `rip server`
|
|
173
|
+
// and friends resolve source binaries from this project's node_modules.
|
|
174
|
+
let meta = {};
|
|
175
|
+
try { meta = JSON.parse(readFileSync(join(target, 'package.json'), 'utf-8')); } catch {}
|
|
176
|
+
const binMap = typeof meta.bin === 'string' ? { [short]: meta.bin } : (meta.bin || {});
|
|
177
|
+
const bins = [];
|
|
178
|
+
for (const [name, rel] of Object.entries(binMap)) {
|
|
179
|
+
const binTarget = join(target, rel);
|
|
180
|
+
if (!existsSync(binTarget)) continue;
|
|
181
|
+
if (linkTo(join(binDir, name), binTarget, 'file')) changed = true;
|
|
182
|
+
bins.push(name);
|
|
183
|
+
}
|
|
184
|
+
linked.push({ dep, bins });
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// The compiler/toolchain itself. Every @rip-lang/* package depends on it,
|
|
188
|
+
// and the loader + VS Code LSP resolve it from the project's node_modules —
|
|
189
|
+
// so it must point at source too, otherwise a published `rip-lang` tarball
|
|
190
|
+
// shadows it (e.g. the LSP loading a typecheck.js without the latest API).
|
|
191
|
+
if (existsSync(join(nodeModules, 'rip-lang'))) {
|
|
192
|
+
if (linkTo(join(nodeModules, 'rip-lang'), src)) changed = true;
|
|
193
|
+
linked.push({ dep: 'rip-lang', bins: [], label: 'compiler' });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (quiet || linked.length === 0) {
|
|
197
|
+
if (linked.length === 0) log('no @rip-lang/* packages resolved to source');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
202
|
+
const tilde = (p) => home && p.startsWith(home) ? '~' + p.slice(home.length) : p;
|
|
203
|
+
const tty = process.stdout.isTTY;
|
|
204
|
+
const dim = (s) => tty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
205
|
+
const bold = (s) => tty ? `\x1b[1m${s}\x1b[0m` : s;
|
|
206
|
+
|
|
207
|
+
const n = linked.length;
|
|
208
|
+
const verb = changed ? 'linked' : 'already linked';
|
|
209
|
+
console.log(`${bold('rip link')} ${dim('·')} ${verb} ${n} package${n === 1 ? '' : 's'} ${dim('→ ' + tilde(src))}`);
|
|
210
|
+
const width = Math.max(...linked.map((l) => l.dep.length));
|
|
211
|
+
for (const { dep, bins, label } of linked) {
|
|
212
|
+
const tag = label || (bins.length ? `bin: ${bins.join(', ')}` : '');
|
|
213
|
+
const line = tag ? `${dep.padEnd(width)}${dim(` ${tag}`)}` : dep;
|
|
214
|
+
console.log(` ${dim('•')} ${line}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
98
218
|
async function main() {
|
|
99
219
|
const args = process.argv.slice(2);
|
|
100
220
|
|
|
@@ -140,14 +260,27 @@ async function main() {
|
|
|
140
260
|
// --- Built-in subcommands ---
|
|
141
261
|
|
|
142
262
|
if (args[0] === 'check') {
|
|
143
|
-
const { runCheck } = await import('../src/typecheck.js');
|
|
144
263
|
const checkArgs = args.slice(1);
|
|
264
|
+
const VALID_FLAGS = new Set(['--audit', '--sourcemap']);
|
|
265
|
+
const unknown = checkArgs.filter(a => a.startsWith('-') && !VALID_FLAGS.has(a));
|
|
266
|
+
if (unknown.length > 0) {
|
|
267
|
+
console.error(`rip check: unknown flag${unknown.length === 1 ? '' : 's'}: ${unknown.join(', ')}`);
|
|
268
|
+
console.error(`Valid flags: ${[...VALID_FLAGS].join(', ')}`);
|
|
269
|
+
process.exit(2);
|
|
270
|
+
}
|
|
145
271
|
const dir = checkArgs.find(a => !a.startsWith('-')) || '.';
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
});
|
|
150
|
-
process.exit(
|
|
272
|
+
const wantAudit = checkArgs.includes('--audit');
|
|
273
|
+
const wantSourcemap = checkArgs.includes('--sourcemap');
|
|
274
|
+
const { runCheck, runAudit } = await import('../src/typecheck.js');
|
|
275
|
+
const checkCode = await runCheck(dir, { sourceMapAudit: wantSourcemap });
|
|
276
|
+
if (!wantAudit) process.exit(checkCode);
|
|
277
|
+
const auditCode = await runAudit(dir);
|
|
278
|
+
process.exit(checkCode || auditCode);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (args[0] === 'link') {
|
|
282
|
+
ripLink(args.slice(1));
|
|
283
|
+
process.exit(0);
|
|
151
284
|
}
|
|
152
285
|
|
|
153
286
|
// --- Subcommand dispatch: rip <name> → rip-<name> ---
|
|
@@ -197,13 +330,32 @@ async function main() {
|
|
|
197
330
|
}
|
|
198
331
|
}
|
|
199
332
|
|
|
200
|
-
// 5.
|
|
333
|
+
// 5. Nearest node_modules/.bin walking up from the cwd. `getRepoRoot`
|
|
334
|
+
// uses `git rev-parse --show-toplevel`, which returns the OUTERMOST git
|
|
335
|
+
// repo — wrong when a project lives in a subdirectory of a larger git
|
|
336
|
+
// repo: step 4 then probes the outer repo's node_modules and misses the
|
|
337
|
+
// project's own declared bins. Resolve the bin the way Node resolves a
|
|
338
|
+
// dependency — nearest node_modules up the tree from the cwd — which is
|
|
339
|
+
// correct for nested projects and standalone consumers alike.
|
|
340
|
+
let nmDir = process.cwd();
|
|
341
|
+
while (true) {
|
|
342
|
+
const nmBin = join(nmDir, 'node_modules', '.bin', `rip-${name}`);
|
|
343
|
+
if (existsSync(nmBin)) {
|
|
344
|
+
const r = spawnSync(nmBin, subArgs, { stdio: 'inherit', env: process.env });
|
|
345
|
+
process.exit(r.status ?? 1);
|
|
346
|
+
}
|
|
347
|
+
const parent = dirname(nmDir);
|
|
348
|
+
if (parent === nmDir) break;
|
|
349
|
+
nmDir = parent;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// 6. Global PATH: rip-<name>
|
|
201
353
|
const pathResult = spawnSync(`rip-${name}`, subArgs, { stdio: 'inherit', env: process.env });
|
|
202
354
|
if (pathResult.error?.code !== 'ENOENT') {
|
|
203
355
|
process.exit(pathResult.status ?? 1);
|
|
204
356
|
}
|
|
205
357
|
|
|
206
|
-
//
|
|
358
|
+
// 7. Not found
|
|
207
359
|
console.error(`rip: unknown command '${name}'\n\nRun 'rip --help' for usage.`);
|
|
208
360
|
process.exit(1);
|
|
209
361
|
}
|
|
@@ -213,7 +365,10 @@ async function main() {
|
|
|
213
365
|
|
|
214
366
|
if ((args.length === 0 && process.stdin.isTTY) || ripOptions.includes('-r') || ripOptions.includes('--repl')) {
|
|
215
367
|
const replModule = join(__dirname, '../src/repl.js');
|
|
216
|
-
|
|
368
|
+
// --preload installs the rip-loader plugin so `import '@rip-lang/foo'`
|
|
369
|
+
// (and any other .rip dependency) compiles when the REPL is run from a
|
|
370
|
+
// directory without a bunfig.toml.
|
|
371
|
+
const replProcess = spawn('bun', ['--experimental-vm-modules', '--preload', loaderPath, '-e', `import('${replModule}').then(m => m.startREPL())`], {
|
|
217
372
|
stdio: 'inherit',
|
|
218
373
|
env: process.env
|
|
219
374
|
});
|
package/docs/AGENTS.md
CHANGED
|
@@ -38,6 +38,6 @@ App.mount()
|
|
|
38
38
|
- `demo.html` and `charts.html` — dashboard demos
|
|
39
39
|
- `sierpinski.html` — CDN demo
|
|
40
40
|
- `example/index.html` and `results/index.html` — app launchers / examples. `example/index.json` is generated from `docs/demo/` via `bun run bundle:demo` (the source-of-truth lives in `docs/demo/`, the JSON is the deployable artifact).
|
|
41
|
-
- `ui/index.html` — widget gallery
|
|
41
|
+
- `ui/index.html` — widget gallery. `ui/bundle.json` is generated from `packages/ui/browser/components/` via `bun run bundle:ui` (auto-runs as part of `bun run build`). The source-of-truth is the workspace package; the JSON is the deployable artifact. The gallery loads the bundle at boot via `data-src="bundle.json"` and reads view-source text synchronously from the in-memory components store (`window.__RIP__.components.read("_pkg/ui/<id>.rip")`) — no per-component fetches.
|
|
42
42
|
|
|
43
43
|
Static demos can be opened via `file://`. The playground and example app require `bun run serve`.
|