feat(api): javascript api for custom ui building#3303
Draft
pankgeorg wants to merge 87 commits into
Draft
Conversation
Member
|
We could factor out the inline definition of create_actions_for(client, {get_state, set_state}) -> PlutoActionsand Editor.js would call it with: create_actions_for(client, {get_state: () => this.state.notebook(), set_state: this.setStatePromise}) |
Member
And it would:
|
Fixes a bug where the serialization creates an invalid toml. This results in spammy logs in the pluto extension
c10a17a to
2344c1b
Compare
Replace brittle string matching with proper TOML parser for cell metadata. This makes the parser more robust and extensible, supporting all TOML data types (booleans, numbers, strings, arrays, etc.) instead of hardcoded patterns. Changes: - Add @iarna/toml dependency for TOML parsing/serialization - Refactor parseCellMetadata() to use TOML.parse() - Refactor serializeCellMetadata() to use TOML.stringify() - Fix merge conflicts in test/test_fs.js 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…all bugs - Delete frontend/api.js (unused since rainbow rewrite) - Delete root and frontend/standalone/ package-lock.json placeholders - Fix stale repository.directory in rainbow package.json (frontend/api -> frontend) - Remove duplicate lodash-es entry from rollup external (already aliased) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rontend/ - Move .parcelrc and parcel-resolver-like-a-browser into frontend/, delete frontend-bundler/ - Replace rollup config with parcel targets in frontend/package.json: main+module (rainbow API), ui-main+ui-module (rainbow ./ui), react-main+react-module (rainbow ./react), pluto (Pluto editor HTML) - Drop @rollup/* and rollup-plugin-* devDeps; pin parcel ~2.12.0 (2.16 has SVG transformer bug) - Move ws from devDeps to deps (used by node-polyfill at runtime) - Move mkdirp to parcel-resolver-like-a-browser's deps (used by require there) - Delete orphan frontend/standalone/package.json (pluto-fs-resolver — never published, deps unused) - Fix custom resolver: defer non-CDN imports to default; add .ts/.tsx fallback for relative .js imports of TS sources; remove forgotten 10s debug sleep - Update CI Bundle.yml/Test.yml/IntegrationTest.yml to point at frontend/ instead of frontend-bundler/ - Untrack frontend/package-lock.json from .gitignore (CI cache key) - Add ws as runtime dep, drop unused webcrypto/memfs/path-browserify/tslib aliases that rollup needed for browser polyfilling Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 tasks
Conflict resolution: - Took main wholesale for translations: lang.js (full i18next removal), lang_imports.js (5 new languages), ErrorMessage.js (real bugfixes + translation key) - Restored sample/Basic mathematics.jl that was accidentally deleted in 801f998 - Dropped local @ts-nocheck workaround on mixedParsers.js, kept the unused-lodash-import cleanup - Merged .parcelrc to keep parcel-resolver-like-a-browser + main's "optimizers": { "*.html": [] } - Folded main's offline build pipeline into the consolidated frontend/ layout: .parcelrc-offline + pluto-offline parcel target + build:editor:offline script + frontend-dist-offline output dir - Bumped parcel and all @parcel/* deps to ^2.16.4 (matches main); SVG transformer error from earlier no longer reproduces with the merged .parcelrc - Added @types/semver and @parcel/transformer-inline (used by offline pipeline) to devDeps Verified: npm run build runs all three pipelines (rainbow, editor, editor offline). Re-packed rainbow and rebuilt @plutojl/cli downstream — still works. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prettier from main's .prettierrc.json (4-space indent, no semi, double quotes, 160 col, ES5 trailing commas) was never run on the rainbow files I added or on the consolidated package.json. Apply it now to bring this branch in line with main's style. .parcelrc / .parcelrc-offline kept multi-line array formatting to match main's existing style (prettier doesn't recognize the extension and main hasn't run prettier on those files either). package-lock.json regen catches up to the parcel ^2.16.4 bump from the merge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
These were wired to the deleted frontend/standalone/package.json (pluto-fs-resolver) which had `test` and `test:e2e` scripts. After the consolidation that package.json is gone and nothing runs these tests: - e2e.test.js was already broken (imports ../dist/index.esm.js, which the parcel rename made dist/index.mjs) - from_dyadgen.test.js + test/test_fs.js are self-runnable but no script wires them - test/fixtures/*.jl, test/README.md, fixtures/ all only existed for those tests None were published (excluded by `files` field), so no consumer impact. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Six fixes from a functional review of the rainbow Worker/Host API consumed by @plutojl/cli (the MCP server in JuliaPluto/advanced-vscode-extension): 1. **from_dyadgen.js**: import `MTOML_CELL_ID`. It was used at line 83 but only `PTOML_CELL_ID` was imported — every call to `from_julia()`/`from_dyadgen()` was throwing `ReferenceError`. 2. **parser.js disabled-cell extraction**: `lastIndexOf(DISABLED_SUFFIX.trim())` overshoots the suffix (skips the leading `\n `), so each parse→serialize→parse cycle accumulated trailing whitespace inside a disabled cell. Use the untrimmed suffix. 3. **client.js `connect()` race**: `this.connected` is only set asynchronously by the connection-status callback; two concurrent `connect()` calls both passed the early-return and spawned two `pluto_connection`s. Replaced with a single-flight `_connecting` promise. 4. **client.js `wait()` listener leak**: if the worker never reached the desired idle state (e.g., disconnected mid-wait), the registered `onUpdate` listener stayed in `_update_handlers` forever. Now also subscribes to `onConnectionStatus` and rejects with "Connection lost while waiting" on disconnect; cleanup runs on every exit path. 5. **client.js `waitSnippet()` listener leak**: same pattern. Default `timeout=-1` plus a disconnect would leak the listener. Same fix; timeout case now rejects with a clearer Error instead of `null`. 6. **client.js `setCellFolded(cell_id, folded)` (new public method)**: addresses an upstream bug in `@plutojl/cli`'s `plutoManager.foldCell`, which was sending the `code_folded` patch via `worker.client.send` directly — bypassing rainbow's `_update_notebook_state` flow, so rainbow's local `notebook_state.cell_inputs[id].code_folded` was never updated. Consumers should call `worker.setCellFolded(id, folded)` instead; it goes through the canonical patch flow that updates server state, local state, and the disk-saved `╠═`/`╟─` cell-order marker consistently. Verified: rainbow rebuilds clean; @plutojl/cli rebuilds against the local pack; `Worker.prototype.setCellFolded` resolves at runtime. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two small additions to the Worker API in response to recurring patterns in @plutojl/cli (JuliaPluto/advanced-vscode-extension): - `Worker.runEphemeral(code, options?)` — addSnippet-then-delete in one call, with guaranteed cleanup of the temporary cell even if the run rejects. Replaces the manual `waitSnippet(0, code)` + `deleteSnippets([id])` pattern in `plutoManager.executeCodeEphemeral`. - `Worker.wait(ready, timeoutMs?)` — added optional timeout. Rejects with a clear Error on timeout (in addition to the existing connection-loss reject). Replaces a 60s polling loop in `plutoTerminal.waitForIdle`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three more rainbow APIs in response to recurring patterns in @plutojl/cli:
- `_apply_patches`: decode `Uint8Array` / `ArrayBuffer` cell-output bodies
to UTF-8 strings when `output.mime` is set. The websocket delivers
msgpack-decoded binary blobs and consumers (HTML/SVG renderers,
postMessage to webview) all expect strings. Closes the
`// TODO: this probably needs to happen at @plutojl/rainbow` in the VSCode
extension's controller.ts.
- `Host.openByPath(path, content, { unlink? })`: bundles the Pluto-quirk
workaround for "open existing notebook by path". Pluto only exposes
"create new from text", so we upload the content, then move the resulting
in-memory notebook to `path` (with a best-effort unlink first because
`moveTo` rejects if `path` already exists). Replaces a 5-line dance in
`plutoManager.getWorker`.
- `Worker.setCellMetadata(cell_id, metadata)`: focused metadata setter,
routed through `_update_notebook_state` like `setCellFolded`. Currently
the only way to set cell metadata was `updateSnippetCode(id, code, run,
metadata)` which forced you to also pass code.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three CI failures from the merge with main: 1. Bundle workflow called `npm run build-offline`, which is the old frontend-bundler script name. Our consolidated `npm run build` already produces both `frontend-dist/` (online) and `frontend-dist-offline/` (offline) in one invocation, so drop the redundant call. 2. Root tsconfig.json runs strict TS checks (`strictNullChecks`, `noUncheckedIndexedAccess`) over `frontend/**/*.js`. The rainbow source under `frontend/standalone/**` was never written to satisfy those strict settings (it has its own `frontend/tsconfig.json` with `strict: false`). Exclude it from the root check; it's still type-checked by the rainbow `typecheck` script. 3. test/Configuration.jl asserts `../tsconfig.json` returns 4xx. URL normalization rewrites that to `/tsconfig.json`, which the static asset handler was happily serving from `frontend/tsconfig.json` (added by this PR for the rainbow build). Add a small denylist of dev/build-only files (tsconfig.json, package.json, lockfiles, .parcelrc) to `serve_asset` so a `Pluto.run!()` against a dev checkout doesn't expose them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Member
|
I still believe we can turn this into a much smaller script. Can you try starting from scratch by adding "build-rainbow": "cd ../frontend && parcel build --no-source-maps --public-url . --dist-dir ../frontend-dist-rainbow --config ../frontend-bundler/.parcelrc-offline ui.ts",That already creates a standalone JS lib, but it needs some tweaking with the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
These are a bunch of utilities extracted from Editor.jl (thank you claude) that allow for easy embedding of Pluto in other web applications.
Try this Pull Request!
Open Julia and type: