-
Notifications
You must be signed in to change notification settings - Fork 143
Split UI components into dedicated packages #948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Extract shared UI components (Button, Icon, Stats) and CSS (variables,
flex, button styles, stats styles) from @moq/hang-ui into a new
@moq/ui-core package. This is the first milestone in restructuring
the codebase to separate watch/publish from @moq/hang.
Files changed:
- js/ui-core/ (new): New @moq/ui-core package with vite lib build,
containing all shared UI components, icons (20 SVGs), stats panel
with providers, and CSS theme variables.
- js/hang-ui/src/shared/ (deleted): Moved entirely into @moq/ui-core.
- js/hang-ui/src/watch/element.tsx: Stats import now from @moq/ui-core.
- js/hang-ui/src/watch/components/{PlayPauseButton,FullscreenButton,
VolumeSlider,StatsButton}.tsx: Button and Icon imports now from
@moq/ui-core instead of relative ../../shared/ paths.
- js/hang-ui/src/publish/components/{CameraSourceButton,FileSourceButton,
ScreenSourceButton,MediaSourceSelector,NothingSourceButton,
MicrophoneSourceButton}.tsx: Same import update as watch components.
- js/hang-ui/src/watch/styles/index.css: CSS @imports updated from
relative ../../shared/ paths to @moq/ui-core package paths.
- js/hang-ui/src/publish/styles/index.css: Same CSS @import update.
- js/hang-ui/package.json: Added @moq/ui-core as peer dependency.
- js/hang-ui/vite.config.ts: Added @moq/ui-core to rollup externals
so it is not bundled into the hang-ui build output.
- js/hang-ui/README.md: Updated project structure and module overview
to reflect that shared/ has moved to @moq/ui-core.
- package.json (root): Added js/ui-core to workspaces array.
- CLAUDE.md: Added ui-core/ to the JS project structure listing.
- README.md (root): Added @moq/ui-core row to the TypeScript packages
table.
- js/docs/restructure-plan.md (new): Full restructuring plan with
8 milestones covering the migration from the current @moq/hang
monolith to separate @moq/watch, @moq/publish, and @moq/ui-core
packages.
Move the watch/subscribe module from @moq/hang into a standalone
@moq/watch package. This separates watch functionality so it can be
consumed independently, and exposes container and util modules from
@moq/hang for shared use.
Files changed:
- js/watch/ (new): New @moq/watch package with tsc build, containing
all 30 watch source files (broadcast, preview, sync, mse, user,
audio/*, video/*, chat/*, location/*), plus worklet.d.ts for vite
worker imports, and README documenting the Web Component and JS API.
- js/hang/src/watch/ (deleted): Moved entirely into @moq/watch.
- js/hang/package.json: Removed ./watch and ./watch/element exports;
added ./container, ./util/hex, and ./util/libav exports so @moq/watch
can import shared modules. Removed watch from sideEffects array.
- js/hang/src/index.ts: Removed 'export * as Watch' barrel re-export
since watch is now its own package.
- js/hang/README.md: Updated import examples and JS API code samples
to reference @moq/watch/element and @moq/watch instead of
@moq/hang/watch. Added note pointing to @moq/watch README.
- js/watch/src/{broadcast,preview,user}.ts: Updated catalog imports
from relative ../catalog to @moq/hang/catalog.
- js/watch/src/{chat,location}/*.ts: Updated catalog imports from
relative ../../catalog to @moq/hang/catalog.
- js/watch/src/audio/{decoder,mse}.ts: Updated catalog, container,
and util imports from relative ../../* to @moq/hang/*.
- js/watch/src/video/{decoder,mse,source}.ts: Same import updates
as audio files.
- js/watch/src/audio/source.ts: Updated catalog import to
@moq/hang/catalog.
- js/ui-core/src/stats/types.ts: Changed Hang.Watch.* type references
to use new 'import * as Watch from @moq/watch' since Watch was
removed from @moq/hang barrel.
- js/ui-core/package.json: Added @moq/watch as peer dependency for
the stats types.
- js/hang-ui/src/watch/{context,element,index}.tsx: Updated imports
from @moq/hang/watch/element to @moq/watch/element.
- js/hang-ui/src/watch/components/BufferControl.tsx: Updated
BufferedRange import from @moq/hang/watch to @moq/watch.
- js/hang-ui/package.json: Added @moq/watch as peer dependency.
- js/hang-ui/vite.config.ts: Added @moq/watch to rollup externals.
- js/hang-demo/src/index.ts: Updated HangWatch import from
@moq/hang/watch/element to @moq/watch/element.
- js/hang-demo/package.json: Added @moq/watch as dependency.
- package.json (root): Added js/watch to workspaces array.
- CLAUDE.md: Added watch/ to the JS project structure listing.
- README.md (root): Added @moq/watch row to the TypeScript packages
table.
Move the publish module from @moq/hang into a standalone @moq/publish
package. This separates publish functionality so it can be consumed
independently, mirroring the @moq/watch extraction in Milestone 2.
Files changed:
- js/publish/ (new): New @moq/publish package with tsc build, containing
all 26 publish source files (broadcast, preview, user, audio/*,
video/*, chat/*, location/*, source/*), plus worklet.d.ts for vite
worker imports, and README documenting the Web Component and JS API.
- js/hang/src/publish/ (deleted): Moved entirely into @moq/publish.
- js/hang/package.json: Removed ./publish and ./publish/element exports;
added ./util/hacks export so @moq/publish can import isFirefox.
Removed publish from sideEffects array.
- js/hang/src/index.ts: Removed 'export * as Publish' barrel re-export
since publish is now its own package.
- js/hang/README.md: Updated import examples and JS API code samples
to reference @moq/publish/element and @moq/publish instead of
@moq/hang/publish. Added notes pointing to @moq/publish README.
- js/publish/src/{broadcast,preview,user}.ts: Updated catalog imports
from relative ../catalog to @moq/hang/catalog.
- js/publish/src/{chat,location}/*.ts: Updated catalog imports from
relative ../../catalog to @moq/hang/catalog.
- js/publish/src/audio/encoder.ts: Updated catalog, container, and
libav imports from relative ../../* to @moq/hang/*.
- js/publish/src/video/encoder.ts: Updated catalog, container, and
hacks imports from relative ../../* to @moq/hang/*.
- js/publish/src/video/index.ts: Updated catalog import to
@moq/hang/catalog.
- js/publish/src/location/index.ts: Changed barrel import
'import { Catalog } from "../.."' to 'import * as Catalog from
@moq/hang/catalog'.
- js/publish/src/index.ts: Updated comment to reference
@moq/publish/element instead of @moq/hang/publish/element.
- js/hang-ui/src/publish/{context,element,index}.tsx: Updated imports
from @moq/hang/publish/element to @moq/publish/element.
- js/hang-ui/package.json: Added @moq/publish as peer dependency.
- js/hang-ui/vite.config.ts: Added @moq/publish to rollup externals.
- js/hang-demo/src/publish.ts: Updated HangPublish import from
@moq/hang/publish/element to @moq/publish/element.
- js/hang-demo/package.json: Added @moq/publish as dependency.
- package.json (root): Added js/publish to workspaces array.
- CLAUDE.md: Added publish/ to the JS project structure listing.
- README.md (root): Added @moq/publish row to the TypeScript packages
table.
Move the watch UI web component from @moq/hang-ui into @moq/watch,
co-locating the UI with the logic it wraps. The <hang-watch-ui>
custom element is now available via @moq/watch/ui.
Files changed:
- js/watch/src/ui/ (new): 15 files moved from hang-ui/src/watch/ —
context.tsx, element.tsx, index.tsx, hooks/use-watch-ui.ts,
styles/index.css, and 10 components (BufferControl, BufferingIndicator,
FullscreenButton, LatencySlider, PlayPauseButton, QualitySelector,
StatsButton, VolumeSlider, WatchControls, WatchStatusIndicator).
- js/watch/src/ui/{context,element,index}.tsx: Updated imports from
@moq/watch/element to ../element and @moq/watch to .. (now local
within the package).
- js/watch/src/ui/components/BufferControl.tsx: Updated BufferedRange
import from @moq/watch to ../.. (local).
- js/watch/package.json: Added ./ui export pointing to src/ui/index.tsx;
added src/ui/index.tsx to sideEffects; added @moq/ui-core dependency;
added solid-element, solid-js, vite, vite-plugin-solid as dev deps;
updated build script to run both tsc and vite.
- js/watch/vite.config.ts (new): Vite lib mode config building the UI
entry point with solid plugin, externalizing @moq/hang, @moq/lite,
@moq/signals, @moq/ui-core. Uses emptyOutDir: false to preserve
tsc output in dist/.
- js/watch/tsconfig.json: Added exclude for src/ui since .tsx files
are built by vite, not tsc.
- js/watch/README.md: Added UI Web Component section documenting
<hang-watch-ui> element and its dependency on @moq/ui-core.
- js/hang-ui/src/watch/ (deleted): Moved entirely into @moq/watch/ui.
- js/hang-ui/package.json: Removed ./watch export and sideEffect;
removed @moq/watch peer dependency.
- js/hang-ui/vite.config.ts: Removed watch entry point and @moq/watch
from rollup externals.
- js/hang-demo/src/index.ts: Updated watch UI import from
@moq/hang-ui/watch to @moq/watch/ui.
Move the publish UI web component from @moq/hang-ui into @moq/publish,
co-locating the UI with the logic it wraps. The <hang-publish-ui>
custom element is now available via @moq/publish/ui.
Files changed:
- js/publish/src/ui/ (new): 17 files moved from hang-ui/src/publish/ —
context.tsx, element.tsx, index.tsx, hooks/use-publish-ui.ts,
styles/{index,controls,media-selector,source-button,status-indicator}.css,
and 8 components (CameraSourceButton, FileSourceButton,
MediaSourceSelector, MicrophoneSourceButton, NothingSourceButton,
PublishControls, PublishStatusIndicator, ScreenSourceButton).
- js/publish/src/ui/{context,element,index}.tsx: Updated imports from
@moq/publish/element to ../element (now local within the package).
- js/publish/package.json: Added ./ui export pointing to src/ui/index.tsx;
added src/ui/index.tsx to sideEffects; added @moq/ui-core dependency;
added solid-element, solid-js, vite, vite-plugin-solid as dev deps;
updated build script to run both tsc and vite.
- js/publish/vite.config.ts (new): Vite lib mode config building the UI
entry point with solid plugin, externalizing @moq/hang, @moq/lite,
@moq/signals, @moq/ui-core. Uses emptyOutDir: false to preserve
tsc output in dist/.
- js/publish/tsconfig.json: Added exclude for src/ui since .tsx files
are built by vite, not tsc.
- js/publish/README.md: Added UI Web Component section documenting
<hang-publish-ui> element and its dependency on @moq/ui-core.
- js/hang-ui/src/publish/ (deleted): Moved entirely into @moq/publish/ui.
- js/hang-ui/package.json: Removed ./publish export, sideEffect, and
all peer dependencies (package is now empty).
- js/hang-ui/vite.config.ts: Removed publish entry point (entry is now
empty object).
- js/hang-demo/src/publish.ts: Updated publish UI import from
@moq/hang-ui/publish to @moq/publish/ui.
Milestone 6 — Remove @moq/hang-ui: - Delete js/hang-ui/ package entirely - Remove @moq/hang-ui dep from hang-demo/package.json - Remove js/hang-ui from root package.json workspaces - Delete doc/js/@moq/hang-ui.md - Update sidebar: replace @moq/hang-ui with @moq/watch, @moq/publish, @moq/ui-core - Update doc/index.md, doc/js/index.md, doc/js/env/web.md references - Update doc/js/@moq/hang/watch.md and publish.md SolidJS sections - Update doc/js/@moq/signals.md import reference - Update all @moq/hang/watch/element → @moq/watch/element imports in docs - Update all @moq/hang/publish/element → @moq/publish/element imports in docs - Update CLAUDE.md: remove hang-ui from structure, update tooling - Update README.md: remove @moq/hang-ui row, update @moq/ui-core description - Create doc pages: @moq/watch.md, @moq/publish.md, @moq/ui-core.md (fix dead links) Milestone 7 — Clean up @moq/hang: - Remove unused deps: comlink, async-mutex (only used by extracted watch/publish) - Rewrite js/hang/README.md for core-only scope (catalog, container, support) - Rewrite doc/js/@moq/hang/index.md for core-only scope - Update README.md @moq/hang description in package table All packages pass bun run check (TypeScript + VitePress build, zero dead links).
The <hang-watch-ui> and <hang-publish-ui> elements work by discovering a nested <hang-watch> / <hang-publish> child — they don't accept url/path attributes directly. Updated all doc examples to show the correct usage: - doc/js/@moq/watch.md - doc/js/@moq/publish.md - doc/js/@moq/hang/watch.md - doc/js/@moq/hang/publish.md
- Container includes both CMAF (fMP4) and Legacy formats, not just CMAF
- Fix CMAF API names in code examples to match actual exports
- Fix Utilities description: hex encoding, Opus polyfill, latency computation, browser workarounds
- Fix hang-watch-ui / hang-publish-ui examples to show correct wrapping pattern
(they discover a nested child element, not accept url/path attributes directly)
Updated: doc/js/@moq/hang/index.md, js/hang/README.md,
doc/js/@moq/watch.md, doc/js/@moq/publish.md,
doc/js/@moq/hang/watch.md, doc/js/@moq/hang/publish.md
- tsconfig.json now includes src/ui with SolidJS JSX settings, used by the IDE and check script for full type coverage - tsconfig.build.json excludes src/ui for tsc -b declaration emit (Vite handles UI compilation) - Added vite-env.d.ts for Vite-specific import types (?raw, ?inline) Affected packages: @moq/watch, @moq/publish
WalkthroughThis pull request restructures the package architecture by separating the monolithic 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
js/ui-core/vite.config.ts (1)
14-16:⚠️ Potential issue | 🟡 MinorAdd
@moq/watchtorollupOptions.external.The package
@moq/watchis imported instats/types.tsfor type definitions but is not listed in theexternalarray, which could cause it to be bundled into the library output instead of being treated as a peer dependency.doc/js/@moq/hang/index.md (1)
80-86:⚠️ Potential issue | 🟡 MinorStale links in "Next Steps" section.
Lines 82–83 still point to
/js/@moq/hang/watchand/js/@moq/hang/publish, but the "Related Packages" section above correctly links to/js/@moq/watchand/js/@moq/publish. These should be updated to match.Proposed fix
## Next Steps -- Learn about [watching streams](/js/@moq/hang/watch) -- Learn about [publishing streams](/js/@moq/hang/publish) +- Learn about [watching streams](/js/@moq/watch) +- Learn about [publishing streams](/js/@moq/publish) - Use [Web Components](/js/env/web) - Use [`@moq/lite`](/js/@moq/lite) for custom protocols - View [code examples](https://github.com/moq-dev/moq/tree/main/js)doc/js/@moq/hang/watch.md (2)
60-85:⚠️ Potential issue | 🟡 MinorJavaScript API examples still use old
@moq/hangimport paths.The Web Component and React/SolidJS sections are updated to
@moq/watch, but the JS API examples on lines 61–85 and 130–141 still useimport * as Hang from "@moq/hang"andHang.Watch.Broadcast(...). These should be updated to use@moq/watchto match the rest of this file.Proposed fix for lines 60-85
```typescript -import * as Hang from "@moq/hang"; +import * as Watch from "@moq/watch"; -const connection = new Hang.Connection("https://relay.example.com/anon"); +const connection = new Hang.Connection("https://relay.example.com/anon"); // Connection still from `@moq/hang` -const watch = new Hang.Watch.Broadcast(connection, { +const watch = new Watch.Broadcast(connection, { enabled: true, name: "alice",
128-141:⚠️ Potential issue | 🟡 MinorSame stale
Hang.Watch.Broadcastreference in the Track Selection example.-const watch = new Hang.Watch.Broadcast(connection, { +const watch = new Watch.Broadcast(connection, {doc/js/@moq/hang/publish.md (1)
60-87:⚠️ Potential issue | 🟡 MinorJavaScript API examples still reference
@moq/hanginstead of@moq/publish.Same issue as in the watch doc — the Web Component and framework integration sections are updated to
@moq/publish, but the JS API examples throughout (lines 62, 66, 94, 106, 141, 162, 176) still useimport * as Hang from "@moq/hang"andHang.Publish.Broadcast(...). These should be migrated to@moq/watch/@moq/publishfor consistency.doc/js/index.md (1)
25-37:⚠️ Potential issue | 🟡 Minor
@moq/hangdescription is stale after the reorganization.The PR refocuses
@moq/hangon core primitives (Catalog, Container, Support), but Lines 29–35 still describe it as a "High-level media library with Web Components." Web Components are now in@moq/watchand@moq/publish. Update this section to reflect the new scope.
🤖 Fix all issues with AI agents
In `@js/publish/README.md`:
- Around line 95-100: The License links in the "## License" section of
js/publish/README.md point to LICENSE-APACHE and LICENSE-MIT in the current
folder but those files live at the repo root; update the links to use the
correct relative paths ("../../LICENSE-APACHE" and "../../LICENSE-MIT") or
alternatively copy the license files into js/publish/ so the existing references
resolve; locate the "## License" header and change the two link targets for
LICENSE-APACHE and LICENSE-MIT accordingly.
In `@js/publish/vite.config.ts`:
- Around line 14-16: The rollupOptions.external array currently only lists
["@moq/hang","@moq/lite","@moq/signals","@moq/ui-core"] and misses externalizing
Solid libraries used by the UI entry points; update the rollupOptions.external
setting (in vite.config.ts) to include "solid-js", "solid-js/web", and
"solid-element" so those runtimes are not bundled into the library output (do
not add "solid-js/store" since it's not used).
In `@js/ui-core/src/stats/types.ts`:
- Around line 3-4: The file imports type symbols from "@moq/watch" (imported as
Watch) creating a circular package dependency between `@moq/ui-core` and
`@moq/watch`; remove the type import from js/ui-core/src/stats/types.ts by moving
the shared types (stats and any backend interfaces referenced here) into
`@moq/ui-core` itself or into a new dedicated package (e.g., `@moq/types`), then
update consumers: export the moved types from the new location and change
`@moq/watch` (and any other package) to import those types from `@moq/ui-core` or
`@moq/types` instead; ensure js/ui-core/src/stats/types.ts no longer references
Watch (or Hang) from `@moq/watch` so dependency flows one-way (watch → ui-core).
🧹 Nitpick comments (5)
js/watch/package.json (1)
28-37: Consider declaringsolid-jsandsolid-elementaspeerDependencies.These packages provide the runtime for the Solid-based web components exported via
./uiand./element. Listing them only asdevDependenciesmeans consumers won't be prompted to install them, and the library build may either bundle them (causing duplicates) or fail at runtime. The same applies tojs/publish/package.json.js/ui-core/package.json (1)
22-34:solid-jsshould be a peer dependency since exports point to raw source files.The
"."export resolves to./src/index.ts(unbundled source), so consumers must havesolid-jsavailable at build time. Keeping it only indevDependenciesmeans consumers won't be warned if it's missing.Proposed fix
"peerDependencies": { "@moq/hang": "workspace:^0.1.0", "@moq/signals": "workspace:^0.1.0", - "@moq/watch": "workspace:^0.1.0" + "@moq/watch": "workspace:^0.1.0", + "solid-js": "^1.9.10" },doc/js/@moq/publish.md (1)
15-19: Consider removing thenpmalternative per project guidelines.The coding guidelines specify using
bunfor all package management. If this doc targets external consumers who may use npm, this is fine — but it's inconsistent with the project convention.As per coding guidelines: "Use
bunfor all TypeScript/JavaScript package management and script execution (not npm, yarn, or pnpm)".js/docs/restructure-plan.md (1)
34-44: Missing language specifier on fenced code block.The dependency graph code block should specify a language (e.g.,
textorplaintext) to satisfy linting and improve rendering.-``` +```text `@moq/lite` ←─────────────────────────────┐js/ui-core/src/stats/types.ts (1)
21-31: The TODO on line 28 is worth addressing now.The comment asks whether to use
Watch.Backendinstead of separately typingWatch.Audio.BackendandWatch.Video.BackendinProviderProps. Since this file is being actively refactored, it would be a good time to clarify the intent and either resolve the TODO or convert it to a tracked issue.Would you like me to open an issue to track this TODO?
| rollupOptions: { | ||
| external: ["@moq/hang", "@moq/lite", "@moq/signals", "@moq/ui-core"], | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, check package.json to see if solid-js is a dev or regular dependency
echo "=== Checking package.json dependencies ==="
jq '.dependencies, .devDependencies' package.json | grep -A 5 -B 5 "solid" || echo "Checking structure..."
echo ""
echo "=== Finding all vite.config files ==="
fd "vite.config" --type f
echo ""
echo "=== Checking current external configurations in vite.config files ==="
fd "vite.config" --type f -x cat {}
echo ""
echo "=== Checking for solid imports in source files ==="
rg "from ['\"]solid" js/publish/src/ js/watch/src/ js/ui-core/src/ --type ts --type tsx -n 2>/dev/null || echo "No direct matches found"Repository: moq-dev/moq
Length of output: 2434
🏁 Script executed:
#!/bin/bash
# Check the full dependency structure
echo "=== Root package.json dependencies and devDependencies ==="
cat package.json | jq '.dependencies, .devDependencies' 2>/dev/null | head -100
echo ""
echo "=== Check workspace packages ==="
# Look for workspace packages that might have their own package.json
fd "package.json" js/ --max-depth 2
echo ""
echo "=== Search for solid in entire js directory ==="
rg "solid" js/ --type json --type ts --type tsx -c 2>/dev/null | head -20
echo ""
echo "=== Check js/publish/src for all imports ==="
find js/publish/src -type f \( -name "*.ts" -o -name "*.tsx" \) -exec echo "File: {}" \; -exec head -30 {} \;Repository: moq-dev/moq
Length of output: 32592
🏁 Script executed:
#!/bin/bash
# Check individual package.json files for solid dependencies
echo "=== js/publish/package.json ==="
cat js/publish/package.json | jq '.dependencies, .devDependencies, .peerDependencies' 2>/dev/null
echo ""
echo "=== js/ui-core/package.json ==="
cat js/ui-core/package.json | jq '.dependencies, .devDependencies, .peerDependencies' 2>/dev/null
echo ""
echo "=== js/watch/package.json ==="
cat js/watch/package.json | jq '.dependencies, .devDependencies, .peerDependencies' 2>/dev/null
echo ""
echo "=== List all solid imports found ==="
rg "from ['\"]solid" js/publish/src/ js/watch/src/ js/ui-core/src/ --type tsx --type ts -A 1 2>/dev/null | head -50Repository: moq-dev/moq
Length of output: 1252
🏁 Script executed:
#!/bin/bash
# Check which solid-js entry points are imported
echo "=== Checking for solid-js/store imports ==="
rg "solid-js/store" js/ --type tsx --type ts 2>/dev/null || echo "No solid-js/store imports found"
echo ""
echo "=== All solid entry point imports ==="
rg "from ['\"]solid" js/ --type tsx --type ts -o 2>/dev/null | sort -u
echo ""
echo "=== Check if any dist files exist ==="
find js/publish/dist js/watch/dist js/ui-core/dist -type f 2>/dev/null | head -20 || echo "No dist files found"Repository: moq-dev/moq
Length of output: 208
🏁 Script executed:
#!/bin/bash
# Look at the actual imports in UI component files
echo "=== Solid imports in js/publish/src/ui/index.tsx ==="
grep -n "from ['\"]solid" js/publish/src/ui/index.tsx
echo ""
echo "=== Solid imports in js/publish/src/ui/context.tsx ==="
grep -n "from ['\"]solid" js/publish/src/ui/context.tsx
echo ""
echo "=== All files with solid imports ==="
grep -r "from ['\"]solid" js/publish/src/ui/ js/watch/src/ui/ 2>/dev/null | cut -d: -f1 | sort -u
echo ""
echo "=== Summary of what is exported from vite config entry points ==="
echo "js/publish builds ui/index entry which exports:"
head -50 js/publish/src/ui/index.tsx | tail -30
echo ""
echo "js/watch builds ui/index entry which exports:"
head -50 js/watch/src/ui/index.tsx | tail -30Repository: moq-dev/moq
Length of output: 2847
Externalize solid-js and solid-element in vite.config for UI builds.
Both js/publish and js/watch export UI entry points that depend on solid-js and solid-element (imported as customElement, createSignal, Show, etc.), but these devDependencies are not externalized. Bundling them into the library output will cause duplicate runtimes for consumers. Include only the imported entry points: "solid-js", "solid-js/web", and "solid-element" (omit solid-js/store, which is not used).
Proposed fix
rollupOptions: {
- external: ["@moq/hang", "@moq/lite", "@moq/signals", "@moq/ui-core"],
+ external: ["@moq/hang", "@moq/lite", "@moq/signals", "@moq/ui-core", "solid-js", "solid-js/web", "solid-element"],
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| rollupOptions: { | |
| external: ["@moq/hang", "@moq/lite", "@moq/signals", "@moq/ui-core"], | |
| }, | |
| rollupOptions: { | |
| external: ["@moq/hang", "@moq/lite", "@moq/signals", "@moq/ui-core", "solid-js", "solid-js/web", "solid-element"], | |
| }, |
🤖 Prompt for AI Agents
In `@js/publish/vite.config.ts` around lines 14 - 16, The rollupOptions.external
array currently only lists
["@moq/hang","@moq/lite","@moq/signals","@moq/ui-core"] and misses externalizing
Solid libraries used by the UI entry points; update the rollupOptions.external
setting (in vite.config.ts) to include "solid-js", "solid-js/web", and
"solid-element" so those runtimes are not bundled into the library output (do
not add "solid-js/store" since it's not used).
- Replace @moq/watch and @moq/hang imports in ui-core/src/stats/types.ts with structural interfaces (Peekable, AudioBackend, VideoBackend) - Remove @moq/watch and @moq/hang from ui-core peerDependencies - Fix LICENSE-APACHE and LICENSE-MIT paths in publish and watch READMEs
The ring-buffer test file was moved to @moq/watch during the reorganization but the test script stayed in @moq/hang, causing CI to fail with 'No tests found'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@js/watch/README.md`:
- Around line 101-102: Update the two license URLs in README lines containing
"Apache License, Version 2.0" and "MIT license" to use HTTPS instead of HTTP;
replace "http://www.apache.org/licenses/LICENSE-2.0" with
"https://www.apache.org/licenses/LICENSE-2.0" and
"http://opensource.org/licenses/MIT" with "https://opensource.org/licenses/MIT"
so both links are secure and consistent.
🧹 Nitpick comments (4)
js/ui-core/src/stats/types.ts (2)
7-9: Consider exportingPeekable<T>for consumer convenience.
Peekable<T>is used in all exported interfaces (AudioBackend,VideoBackend) but isn't exported itself. Consumers who need to construct objects conforming to these interfaces (e.g., in tests or custom backends) would benefit from being able to reference this type directly rather than re-declaring it.♻️ Suggested change
-interface Peekable<T> { +export interface Peekable<T> { peek(): T; }
21-27:source.tracktyped asPeekable<unknown>loses type safety.Other fields use specific shapes (e.g.,
confighassampleRate,numberOfChannels,codec), buttrackisPeekable<unknown>. If stats providers actually read properties from the track value, this forces unsafe casts downstream. If the track is only checked for presence/absence,unknownis acceptable.js/ui-core/src/index.ts (1)
4-4:AudioBackendandVideoBackendare not re-exported but are part of the public API surface.
ProviderPropsreferencesAudioBackendandVideoBackend, so consumers who need to type individual backend parameters (e.g., passing just the audio backend to a helper) can't import those types from@moq/ui-core.♻️ Suggested change
-export type { KnownStatsProviders, ProviderContext, ProviderProps } from "./stats/types"; +export type { AudioBackend, KnownStatsProviders, Peekable, ProviderContext, ProviderProps, VideoBackend } from "./stats/types";js/watch/src/ui/components/BufferControl.tsx (1)
39-43: Consider extracting color literals to named constants.The hex color strings are used as semantic indicators (red = buffering, yellow = gap, green = healthy) but are inline magic values. Named constants would improve readability.
As per coding guidelines: "Avoid using magic numbers; use named constants instead."
♻️ Suggested change
+const BUFFER_COLOR_BUFFERING = "#f87171"; // red +const BUFFER_COLOR_GAP = "#facc15"; // yellow +const BUFFER_COLOR_HEALTHY = "#4ade80"; // green + const rangeColor = (index: number, isBuffering: boolean) => { - if (isBuffering) return "#f87171"; // red - if (index > 0) return "#facc15"; // yellow - return "#4ade80"; // green + if (isBuffering) return BUFFER_COLOR_BUFFERING; + if (index > 0) return BUFFER_COLOR_GAP; + return BUFFER_COLOR_HEALTHY; };
| - Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) | ||
| - MIT license ([LICENSE-MIT](../../LICENSE-MIT) or http://opensource.org/licenses/MIT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use HTTPS for license URLs.
The license links currently use http. Prefer https for security and consistency.
Suggested fix
-- Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
-- MIT license ([LICENSE-MIT](../../LICENSE-MIT) or http://opensource.org/licenses/MIT)
+- Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
+- MIT license ([LICENSE-MIT](../../LICENSE-MIT) or https://opensource.org/licenses/MIT)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) | |
| - MIT license ([LICENSE-MIT](../../LICENSE-MIT) or http://opensource.org/licenses/MIT) | |
| - Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0) | |
| - MIT license ([LICENSE-MIT](../../LICENSE-MIT) or https://opensource.org/licenses/MIT) |
🤖 Prompt for AI Agents
In `@js/watch/README.md` around lines 101 - 102, Update the two license URLs in
README lines containing "Apache License, Version 2.0" and "MIT license" to use
HTTPS instead of HTTP; replace "http://www.apache.org/licenses/LICENSE-2.0" with
"https://www.apache.org/licenses/LICENSE-2.0" and
"http://opensource.org/licenses/MIT" with "https://opensource.org/licenses/MIT"
so both links are secure and consistent.
|
Oh sorry, the Nix stuff should have been fixed by #952, but it's still good to have. The quiche backend doesn't quite work so I disabled it by default. |
| "./container": "./src/container/index.ts", | ||
| "./util/hex": "./src/util/hex.ts", | ||
| "./util/libav": "./src/util/libav.ts", | ||
| "./util/hacks": "./src/util/hacks.ts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels bad. Maybe just export util?
We could make separate packages for stuff like libav I guess.
Other stuff you could probably just copy-paste (ex. hex). Not a huge deal.
| "rootDir": ".", | ||
| "outDir": "dist", | ||
| "jsx": "preserve", | ||
| "jsxImportSource": "solid-js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm maybe this should be in ui instead.
| @@ -1,18 +1,17 @@ | |||
| { | |||
| "name": "@moq/hang-ui", | |||
| "name": "@moq/ui-core", | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: @moq/theme?
Split UI components into dedicated packages
Extracts watch, publish, and shared UI code out of
@moq/hanginto their own packages, establishing clearer boundaries between media logic and UI.Changes
@moq/ui-core(new) — Shared UI primitives (Button, Icon, Stats panel) used by both watch and publish UIs. Uses structural interfaces for stats provider types to avoid depending on@moq/watchor@moq/hang.@moq/watch(new) — Watch/subscribe logic + optional@moq/watch/uioverlay (<hang-watch-ui>), built with Vite + SolidJS.@moq/publish(new) — Publish logic + optional@moq/publish/uioverlay (<hang-publish-ui>), built with Vite + SolidJS.@moq/hang— Removed all watch/publish/UI code. Now contains only the core media layer: catalog, container (CMAF + Legacy), and utilities.Build
Each package has two TypeScript configs:
Documentation
doc/js/pages and package READMEs to reflect the new structureNix
gitandcmaketo flake.nixrustDeps— required byboring-systo build BoringSSL