@overcrow/mcp 0.0.0 → 0.1.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/LICENSE +21 -0
- package/README.md +91 -1
- package/dist/audit/index.js +103 -0
- package/dist/audit/lexer.js +417 -0
- package/dist/audit/project.js +200 -0
- package/dist/audit/rules.js +661 -0
- package/dist/bootstrap/download.js +229 -0
- package/dist/bootstrap/install.js +280 -0
- package/dist/bootstrap/pin.js +85 -0
- package/dist/bootstrap/pin.json +119 -0
- package/dist/bootstrap/zip.js +258 -0
- package/dist/cli.js +200 -0
- package/dist/confine.js +244 -0
- package/dist/content/docs/en/cli.md +768 -0
- package/dist/content/docs/en/creator-space.md +78 -0
- package/dist/content/docs/en/dev-channel.md +130 -0
- package/dist/content/docs/en/elements.md +469 -0
- package/dist/content/docs/en/forms.md +328 -0
- package/dist/content/docs/en/guide.md +252 -0
- package/dist/content/docs/en/index.md +85 -0
- package/dist/content/docs/en/limits.md +241 -0
- package/dist/content/docs/en/logic.md +446 -0
- package/dist/content/docs/en/manifest.md +388 -0
- package/dist/content/docs/en/mcp.md +165 -0
- package/dist/content/docs/en/package.md +131 -0
- package/dist/content/docs/en/publish-a-widget.md +94 -0
- package/dist/content/docs/en/publish-keys.md +95 -0
- package/dist/content/docs/en/publishing.md +167 -0
- package/dist/content/docs/en/reference.md +55 -0
- package/dist/content/docs/en/result-shapes.md +332 -0
- package/dist/content/docs/en/sdk.md +295 -0
- package/dist/content/docs/en/security.md +115 -0
- package/dist/content/docs/en/service-reference.md +344 -0
- package/dist/content/docs/en/services.md +517 -0
- package/dist/content/docs/en/style-properties.md +270 -0
- package/dist/content/docs/en/style.md +266 -0
- package/dist/content/docs/en/testing.md +400 -0
- package/dist/content/docs/en/verified-domain.md +46 -0
- package/dist/content/docs/en/view.md +338 -0
- package/dist/content/docs/en/widget-listing.md +65 -0
- package/dist/content/docs/en/widget-review.md +57 -0
- package/dist/content/docs/en/widget-statistics.md +134 -0
- package/dist/content/docs/en/widgets.md +76 -0
- package/dist/content/docs/fr/cli.md +802 -0
- package/dist/content/docs/fr/creator-space.md +83 -0
- package/dist/content/docs/fr/dev-channel.md +140 -0
- package/dist/content/docs/fr/elements.md +475 -0
- package/dist/content/docs/fr/forms.md +341 -0
- package/dist/content/docs/fr/guide.md +263 -0
- package/dist/content/docs/fr/index.md +90 -0
- package/dist/content/docs/fr/limits.md +244 -0
- package/dist/content/docs/fr/logic.md +461 -0
- package/dist/content/docs/fr/manifest.md +401 -0
- package/dist/content/docs/fr/mcp.md +173 -0
- package/dist/content/docs/fr/package.md +139 -0
- package/dist/content/docs/fr/publish-a-widget.md +101 -0
- package/dist/content/docs/fr/publish-keys.md +97 -0
- package/dist/content/docs/fr/publishing.md +177 -0
- package/dist/content/docs/fr/reference.md +59 -0
- package/dist/content/docs/fr/result-shapes.md +333 -0
- package/dist/content/docs/fr/sdk.md +301 -0
- package/dist/content/docs/fr/security.md +129 -0
- package/dist/content/docs/fr/service-reference.md +346 -0
- package/dist/content/docs/fr/services.md +540 -0
- package/dist/content/docs/fr/style-properties.md +272 -0
- package/dist/content/docs/fr/style.md +281 -0
- package/dist/content/docs/fr/testing.md +417 -0
- package/dist/content/docs/fr/verified-domain.md +49 -0
- package/dist/content/docs/fr/view.md +352 -0
- package/dist/content/docs/fr/widget-listing.md +69 -0
- package/dist/content/docs/fr/widget-review.md +59 -0
- package/dist/content/docs/fr/widget-statistics.md +141 -0
- package/dist/content/docs/fr/widgets.md +81 -0
- package/dist/content/examples/clock/LICENSE +21 -0
- package/dist/content/examples/clock/README.md +75 -0
- package/dist/content/examples/clock/listing.json +19 -0
- package/dist/content/examples/clock/locales/en.json +4 -0
- package/dist/content/examples/clock/locales/fr.json +4 -0
- package/dist/content/examples/clock/logic.ts +85 -0
- package/dist/content/examples/clock/manifest.json +44 -0
- package/dist/content/examples/clock/package.json +16 -0
- package/dist/content/examples/clock/style.ocss +26 -0
- package/dist/content/examples/clock/tests/hidden.scenario.json +68 -0
- package/dist/content/examples/clock/tests/load-logic.mjs +22 -0
- package/dist/content/examples/clock/tests/logic.test.mjs +89 -0
- package/dist/content/examples/clock/tests/options.scenario.json +108 -0
- package/dist/content/examples/clock/tests/preview.scenario.json +25 -0
- package/dist/content/examples/clock/tests/render.scenario.json +94 -0
- package/dist/content/examples/clock/tests/summer-time.scenario.json +74 -0
- package/dist/content/examples/clock/tests/ticks.scenario.json +120 -0
- package/dist/content/examples/clock/tsconfig.json +16 -0
- package/dist/content/examples/clock/view.ocml +8 -0
- package/dist/content/examples/countdown/LICENSE +20 -0
- package/dist/content/examples/countdown/listing.json +10 -0
- package/dist/content/examples/countdown/locales/en.json +15 -0
- package/dist/content/examples/countdown/locales/fr.json +15 -0
- package/dist/content/examples/countdown/logic.ts +179 -0
- package/dist/content/examples/countdown/manifest.json +34 -0
- package/dist/content/examples/countdown/package.json +15 -0
- package/dist/content/examples/countdown/style.ocss +94 -0
- package/dist/content/examples/countdown/tsconfig.json +16 -0
- package/dist/content/examples/countdown/view.ocml +42 -0
- package/dist/content/examples/fps/LICENSE +21 -0
- package/dist/content/examples/fps/README.md +64 -0
- package/dist/content/examples/fps/listing.json +19 -0
- package/dist/content/examples/fps/locales/en.json +11 -0
- package/dist/content/examples/fps/locales/fr.json +11 -0
- package/dist/content/examples/fps/logic.ts +64 -0
- package/dist/content/examples/fps/manifest.json +30 -0
- package/dist/content/examples/fps/package.json +16 -0
- package/dist/content/examples/fps/style.ocss +31 -0
- package/dist/content/examples/fps/submission.json +8 -0
- package/dist/content/examples/fps/tests/label.scenario.json +63 -0
- package/dist/content/examples/fps/tests/load-logic.mjs +22 -0
- package/dist/content/examples/fps/tests/logic.test.mjs +60 -0
- package/dist/content/examples/fps/tests/preview.scenario.json +29 -0
- package/dist/content/examples/fps/tests/refused.scenario.json +20 -0
- package/dist/content/examples/fps/tests/render.scenario.json +96 -0
- package/dist/content/examples/fps/tests/stale.scenario.json +91 -0
- package/dist/content/examples/fps/tests/unavailable.scenario.json +111 -0
- package/dist/content/examples/fps/tsconfig.json +16 -0
- package/dist/content/examples/fps/view.ocml +11 -0
- package/dist/content/examples/media/LICENSE +21 -0
- package/dist/content/examples/media/README.md +147 -0
- package/dist/content/examples/media/listing.json +19 -0
- package/dist/content/examples/media/locales/en.json +11 -0
- package/dist/content/examples/media/locales/fr.json +11 -0
- package/dist/content/examples/media/logic.ts +191 -0
- package/dist/content/examples/media/manifest.json +35 -0
- package/dist/content/examples/media/package.json +16 -0
- package/dist/content/examples/media/style.ocss +148 -0
- package/dist/content/examples/media/submission.json +12 -0
- package/dist/content/examples/media/tests/covers.scenario.json +144 -0
- package/dist/content/examples/media/tests/gesture.scenario.json +173 -0
- package/dist/content/examples/media/tests/load-logic.mjs +22 -0
- package/dist/content/examples/media/tests/logic.test.mjs +176 -0
- package/dist/content/examples/media/tests/marquee.scenario.json +127 -0
- package/dist/content/examples/media/tests/preview.scenario.json +52 -0
- package/dist/content/examples/media/tests/read-only.scenario.json +53 -0
- package/dist/content/examples/media/tests/refused.scenario.json +22 -0
- package/dist/content/examples/media/tests/refused.test.mjs +31 -0
- package/dist/content/examples/media/tests/render.scenario.json +136 -0
- package/dist/content/examples/media/tests/states.scenario.json +257 -0
- package/dist/content/examples/media/tests/unavailable.scenario.json +120 -0
- package/dist/content/examples/media/tsconfig.json +16 -0
- package/dist/content/examples/media/view.ocml +41 -0
- package/dist/content/examples/notes/LICENSE +21 -0
- package/dist/content/examples/notes/README.md +219 -0
- package/dist/content/examples/notes/listing.json +19 -0
- package/dist/content/examples/notes/locales/en.json +25 -0
- package/dist/content/examples/notes/locales/fr.json +25 -0
- package/dist/content/examples/notes/logic.ts +799 -0
- package/dist/content/examples/notes/manifest.json +40 -0
- package/dist/content/examples/notes/package.json +16 -0
- package/dist/content/examples/notes/style.ocss +469 -0
- package/dist/content/examples/notes/submission.json +12 -0
- package/dist/content/examples/notes/tests/checks.scenario.json +237 -0
- package/dist/content/examples/notes/tests/create.scenario.json +260 -0
- package/dist/content/examples/notes/tests/delete.scenario.json +342 -0
- package/dist/content/examples/notes/tests/drafts.scenario.json +714 -0
- package/dist/content/examples/notes/tests/editor.scenario.json +232 -0
- package/dist/content/examples/notes/tests/frame.scenario.json +93 -0
- package/dist/content/examples/notes/tests/interactive.scenario.json +344 -0
- package/dist/content/examples/notes/tests/limits.scenario.json +1351 -0
- package/dist/content/examples/notes/tests/load-logic.mjs +22 -0
- package/dist/content/examples/notes/tests/logic.test.mjs +514 -0
- package/dist/content/examples/notes/tests/preview.scenario.json +99 -0
- package/dist/content/examples/notes/tests/read-only.scenario.json +105 -0
- package/dist/content/examples/notes/tests/refused.scenario.json +33 -0
- package/dist/content/examples/notes/tests/save.scenario.json +378 -0
- package/dist/content/examples/notes/tests/states.scenario.json +640 -0
- package/dist/content/examples/notes/tests/typing.scenario.json +562 -0
- package/dist/content/examples/notes/tests/unavailable.scenario.json +246 -0
- package/dist/content/examples/notes/tsconfig.json +16 -0
- package/dist/content/examples/notes/view.ocml +154 -0
- package/dist/content/examples/performance/LICENSE +21 -0
- package/dist/content/examples/performance/README.md +134 -0
- package/dist/content/examples/performance/listing.json +19 -0
- package/dist/content/examples/performance/locales/en.json +20 -0
- package/dist/content/examples/performance/locales/fr.json +20 -0
- package/dist/content/examples/performance/logic.ts +210 -0
- package/dist/content/examples/performance/manifest.json +83 -0
- package/dist/content/examples/performance/package.json +16 -0
- package/dist/content/examples/performance/style.ocss +75 -0
- package/dist/content/examples/performance/submission.json +12 -0
- package/dist/content/examples/performance/tests/fahrenheit.scenario.json +110 -0
- package/dist/content/examples/performance/tests/horizontal.scenario.json +96 -0
- package/dist/content/examples/performance/tests/load-logic.mjs +22 -0
- package/dist/content/examples/performance/tests/logic.test.mjs +226 -0
- package/dist/content/examples/performance/tests/menu.scenario.json +170 -0
- package/dist/content/examples/performance/tests/no-fps-source.scenario.json +47 -0
- package/dist/content/examples/performance/tests/preview.scenario.json +45 -0
- package/dist/content/examples/performance/tests/refused.scenario.json +20 -0
- package/dist/content/examples/performance/tests/refused.test.mjs +19 -0
- package/dist/content/examples/performance/tests/region.scenario.json +89 -0
- package/dist/content/examples/performance/tests/render.scenario.json +112 -0
- package/dist/content/examples/performance/tests/sources.scenario.json +151 -0
- package/dist/content/examples/performance/tests/stale.scenario.json +111 -0
- package/dist/content/examples/performance/tests/telemetry-only.scenario.json +44 -0
- package/dist/content/examples/performance/tests/thresholds.scenario.json +147 -0
- package/dist/content/examples/performance/tests/waiting.scenario.json +105 -0
- package/dist/content/examples/performance/tsconfig.json +16 -0
- package/dist/content/examples/performance/view.ocml +18 -0
- package/dist/content/examples/playervox-journal/LICENSE +21 -0
- package/dist/content/examples/playervox-journal/README.md +150 -0
- package/dist/content/examples/playervox-journal/listing.json +19 -0
- package/dist/content/examples/playervox-journal/locales/en.json +25 -0
- package/dist/content/examples/playervox-journal/locales/fr.json +25 -0
- package/dist/content/examples/playervox-journal/logic.ts +556 -0
- package/dist/content/examples/playervox-journal/manifest.json +19 -0
- package/dist/content/examples/playervox-journal/package.json +16 -0
- package/dist/content/examples/playervox-journal/style.ocss +142 -0
- package/dist/content/examples/playervox-journal/submission.json +12 -0
- package/dist/content/examples/playervox-journal/tests/changes.scenario.json +482 -0
- package/dist/content/examples/playervox-journal/tests/delete.scenario.json +432 -0
- package/dist/content/examples/playervox-journal/tests/frame.scenario.json +169 -0
- package/dist/content/examples/playervox-journal/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-journal/tests/logic.test.mjs +349 -0
- package/dist/content/examples/playervox-journal/tests/paging.scenario.json +428 -0
- package/dist/content/examples/playervox-journal/tests/preview.scenario.json +184 -0
- package/dist/content/examples/playervox-journal/tests/read-only.scenario.json +157 -0
- package/dist/content/examples/playervox-journal/tests/refused.scenario.json +39 -0
- package/dist/content/examples/playervox-journal/tests/scale.scenario.json +286 -0
- package/dist/content/examples/playervox-journal/tests/signed-out.scenario.json +134 -0
- package/dist/content/examples/playervox-journal/tests/states.scenario.json +741 -0
- package/dist/content/examples/playervox-journal/tests/unavailable.scenario.json +183 -0
- package/dist/content/examples/playervox-journal/tsconfig.json +16 -0
- package/dist/content/examples/playervox-journal/view.ocml +52 -0
- package/dist/content/examples/playervox-rating/LICENSE +21 -0
- package/dist/content/examples/playervox-rating/README.md +166 -0
- package/dist/content/examples/playervox-rating/listing.json +19 -0
- package/dist/content/examples/playervox-rating/locales/en.json +35 -0
- package/dist/content/examples/playervox-rating/locales/fr.json +35 -0
- package/dist/content/examples/playervox-rating/logic.ts +581 -0
- package/dist/content/examples/playervox-rating/manifest.json +19 -0
- package/dist/content/examples/playervox-rating/package.json +16 -0
- package/dist/content/examples/playervox-rating/style.ocss +333 -0
- package/dist/content/examples/playervox-rating/submission.json +12 -0
- package/dist/content/examples/playervox-rating/tests/account.scenario.json +125 -0
- package/dist/content/examples/playervox-rating/tests/bounds.scenario.json +73 -0
- package/dist/content/examples/playervox-rating/tests/draft.scenario.json +199 -0
- package/dist/content/examples/playervox-rating/tests/form.scenario.json +142 -0
- package/dist/content/examples/playervox-rating/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-rating/tests/logic.test.mjs +346 -0
- package/dist/content/examples/playervox-rating/tests/offline.scenario.json +142 -0
- package/dist/content/examples/playervox-rating/tests/preview.scenario.json +44 -0
- package/dist/content/examples/playervox-rating/tests/publish-keyboard.scenario.json +221 -0
- package/dist/content/examples/playervox-rating/tests/publish-pointer.scenario.json +314 -0
- package/dist/content/examples/playervox-rating/tests/read-only.scenario.json +70 -0
- package/dist/content/examples/playervox-rating/tests/refused.scenario.json +45 -0
- package/dist/content/examples/playervox-rating/tests/states.scenario.json +362 -0
- package/dist/content/examples/playervox-rating/tsconfig.json +16 -0
- package/dist/content/examples/playervox-rating/view.ocml +62 -0
- package/dist/content/examples/playervox-reviews/LICENSE +21 -0
- package/dist/content/examples/playervox-reviews/README.md +194 -0
- package/dist/content/examples/playervox-reviews/listing.json +19 -0
- package/dist/content/examples/playervox-reviews/locales/en.json +32 -0
- package/dist/content/examples/playervox-reviews/locales/fr.json +32 -0
- package/dist/content/examples/playervox-reviews/logic.ts +822 -0
- package/dist/content/examples/playervox-reviews/manifest.json +30 -0
- package/dist/content/examples/playervox-reviews/package.json +16 -0
- package/dist/content/examples/playervox-reviews/style.ocss +260 -0
- package/dist/content/examples/playervox-reviews/submission.json +8 -0
- package/dist/content/examples/playervox-reviews/tests/account.scenario.json +249 -0
- package/dist/content/examples/playervox-reviews/tests/bounds.scenario.json +336 -0
- package/dist/content/examples/playervox-reviews/tests/changes.scenario.json +515 -0
- package/dist/content/examples/playervox-reviews/tests/filter.scenario.json +400 -0
- package/dist/content/examples/playervox-reviews/tests/frame.scenario.json +185 -0
- package/dist/content/examples/playervox-reviews/tests/keyboard.scenario.json +188 -0
- package/dist/content/examples/playervox-reviews/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-reviews/tests/logic.test.mjs +559 -0
- package/dist/content/examples/playervox-reviews/tests/offline-start.scenario.json +152 -0
- package/dist/content/examples/playervox-reviews/tests/offline.scenario.json +311 -0
- package/dist/content/examples/playervox-reviews/tests/paging.scenario.json +497 -0
- package/dist/content/examples/playervox-reviews/tests/preview.scenario.json +286 -0
- package/dist/content/examples/playervox-reviews/tests/reading.scenario.json +591 -0
- package/dist/content/examples/playervox-reviews/tests/refused.scenario.json +54 -0
- package/dist/content/examples/playervox-reviews/tests/scale.scenario.json +303 -0
- package/dist/content/examples/playervox-reviews/tests/states.scenario.json +700 -0
- package/dist/content/examples/playervox-reviews/tests/unavailable.scenario.json +192 -0
- package/dist/content/examples/playervox-reviews/tsconfig.json +16 -0
- package/dist/content/examples/playervox-reviews/view.ocml +110 -0
- package/dist/content/examples/playervox-score/LICENSE +21 -0
- package/dist/content/examples/playervox-score/README.md +131 -0
- package/dist/content/examples/playervox-score/listing.json +19 -0
- package/dist/content/examples/playervox-score/locales/en.json +23 -0
- package/dist/content/examples/playervox-score/locales/fr.json +23 -0
- package/dist/content/examples/playervox-score/logic.ts +430 -0
- package/dist/content/examples/playervox-score/manifest.json +47 -0
- package/dist/content/examples/playervox-score/package.json +16 -0
- package/dist/content/examples/playervox-score/style.ocss +247 -0
- package/dist/content/examples/playervox-score/submission.json +8 -0
- package/dist/content/examples/playervox-score/tests/grades.scenario.json +279 -0
- package/dist/content/examples/playervox-score/tests/load-logic.mjs +22 -0
- package/dist/content/examples/playervox-score/tests/logic.test.mjs +229 -0
- package/dist/content/examples/playervox-score/tests/options.scenario.json +302 -0
- package/dist/content/examples/playervox-score/tests/preview.scenario.json +68 -0
- package/dist/content/examples/playervox-score/tests/pulse.scenario.json +157 -0
- package/dist/content/examples/playervox-score/tests/refused.scenario.json +21 -0
- package/dist/content/examples/playervox-score/tests/signed-out.scenario.json +46 -0
- package/dist/content/examples/playervox-score/tests/states.scenario.json +450 -0
- package/dist/content/examples/playervox-score/tests/unavailable.scenario.json +84 -0
- package/dist/content/examples/playervox-score/tsconfig.json +16 -0
- package/dist/content/examples/playervox-score/view.ocml +51 -0
- package/dist/content/examples/session/LICENSE +21 -0
- package/dist/content/examples/session/README.md +57 -0
- package/dist/content/examples/session/listing.json +19 -0
- package/dist/content/examples/session/locales/en.json +3 -0
- package/dist/content/examples/session/locales/fr.json +3 -0
- package/dist/content/examples/session/logic.ts +26 -0
- package/dist/content/examples/session/manifest.json +19 -0
- package/dist/content/examples/session/package.json +16 -0
- package/dist/content/examples/session/style.ocss +16 -0
- package/dist/content/examples/session/submission.json +8 -0
- package/dist/content/examples/session/tests/hidden.scenario.json +45 -0
- package/dist/content/examples/session/tests/load-logic.mjs +22 -0
- package/dist/content/examples/session/tests/logic.test.mjs +37 -0
- package/dist/content/examples/session/tests/preview.scenario.json +28 -0
- package/dist/content/examples/session/tests/refused.scenario.json +20 -0
- package/dist/content/examples/session/tests/refused.test.mjs +16 -0
- package/dist/content/examples/session/tests/render.scenario.json +95 -0
- package/dist/content/examples/session/tests/ticks.scenario.json +139 -0
- package/dist/content/examples/session/tests/unknown.scenario.json +37 -0
- package/dist/content/examples/session/tsconfig.json +16 -0
- package/dist/content/examples/session/view.ocml +11 -0
- package/dist/content/examples/stopwatch/LICENSE +21 -0
- package/dist/content/examples/stopwatch/README.md +99 -0
- package/dist/content/examples/stopwatch/listing.json +19 -0
- package/dist/content/examples/stopwatch/locales/en.json +8 -0
- package/dist/content/examples/stopwatch/locales/fr.json +8 -0
- package/dist/content/examples/stopwatch/logic.ts +93 -0
- package/dist/content/examples/stopwatch/manifest.json +19 -0
- package/dist/content/examples/stopwatch/package.json +16 -0
- package/dist/content/examples/stopwatch/style.ocss +54 -0
- package/dist/content/examples/stopwatch/submission.json +12 -0
- package/dist/content/examples/stopwatch/tests/errors.scenario.json +121 -0
- package/dist/content/examples/stopwatch/tests/gesture.scenario.json +154 -0
- package/dist/content/examples/stopwatch/tests/hidden.scenario.json +57 -0
- package/dist/content/examples/stopwatch/tests/hundredths.scenario.json +173 -0
- package/dist/content/examples/stopwatch/tests/load-logic.mjs +22 -0
- package/dist/content/examples/stopwatch/tests/logic.test.mjs +99 -0
- package/dist/content/examples/stopwatch/tests/preview.scenario.json +36 -0
- package/dist/content/examples/stopwatch/tests/read-only.scenario.json +42 -0
- package/dist/content/examples/stopwatch/tests/read-only.test.mjs +18 -0
- package/dist/content/examples/stopwatch/tests/refused.scenario.json +22 -0
- package/dist/content/examples/stopwatch/tests/refused.test.mjs +18 -0
- package/dist/content/examples/stopwatch/tests/render.scenario.json +105 -0
- package/dist/content/examples/stopwatch/tests/states.scenario.json +246 -0
- package/dist/content/examples/stopwatch/tests/unknown.scenario.json +40 -0
- package/dist/content/examples/stopwatch/tsconfig.json +16 -0
- package/dist/content/examples/stopwatch/view.ocml +29 -0
- package/dist/content/examples/twitch-chat/LICENSE +21 -0
- package/dist/content/examples/twitch-chat/README.md +283 -0
- package/dist/content/examples/twitch-chat/listing.json +19 -0
- package/dist/content/examples/twitch-chat/locales/en.json +52 -0
- package/dist/content/examples/twitch-chat/locales/fr.json +52 -0
- package/dist/content/examples/twitch-chat/logic.ts +887 -0
- package/dist/content/examples/twitch-chat/manifest.json +33 -0
- package/dist/content/examples/twitch-chat/package.json +16 -0
- package/dist/content/examples/twitch-chat/style.ocss +544 -0
- package/dist/content/examples/twitch-chat/submission.json +12 -0
- package/dist/content/examples/twitch-chat/tests/account.scenario.json +325 -0
- package/dist/content/examples/twitch-chat/tests/burst.scenario.json +1866 -0
- package/dist/content/examples/twitch-chat/tests/channel-refused.scenario.json +372 -0
- package/dist/content/examples/twitch-chat/tests/channel.scenario.json +480 -0
- package/dist/content/examples/twitch-chat/tests/draft.scenario.json +279 -0
- package/dist/content/examples/twitch-chat/tests/fade.scenario.json +269 -0
- package/dist/content/examples/twitch-chat/tests/failures.scenario.json +420 -0
- package/dist/content/examples/twitch-chat/tests/favorites.scenario.json +376 -0
- package/dist/content/examples/twitch-chat/tests/frame.scenario.json +152 -0
- package/dist/content/examples/twitch-chat/tests/lifetime.scenario.json +186 -0
- package/dist/content/examples/twitch-chat/tests/load-logic.mjs +22 -0
- package/dist/content/examples/twitch-chat/tests/logic.test.mjs +1053 -0
- package/dist/content/examples/twitch-chat/tests/passive.scenario.json +536 -0
- package/dist/content/examples/twitch-chat/tests/preview.scenario.json +147 -0
- package/dist/content/examples/twitch-chat/tests/read-only.scenario.json +202 -0
- package/dist/content/examples/twitch-chat/tests/read-only.test.mjs +63 -0
- package/dist/content/examples/twitch-chat/tests/refused.scenario.json +65 -0
- package/dist/content/examples/twitch-chat/tests/refused.test.mjs +43 -0
- package/dist/content/examples/twitch-chat/tests/render.scenario.json +347 -0
- package/dist/content/examples/twitch-chat/tests/reply.scenario.json +384 -0
- package/dist/content/examples/twitch-chat/tests/send-refused.scenario.json +383 -0
- package/dist/content/examples/twitch-chat/tests/send.scenario.json +300 -0
- package/dist/content/examples/twitch-chat/tests/states.scenario.json +455 -0
- package/dist/content/examples/twitch-chat/tests/unavailable.scenario.json +256 -0
- package/dist/content/examples/twitch-chat/tests/unread.scenario.json +997 -0
- package/dist/content/examples/twitch-chat/tsconfig.json +16 -0
- package/dist/content/examples/twitch-chat/view.ocml +141 -0
- package/dist/content/examples/warframe-market/LICENSE +21 -0
- package/dist/content/examples/warframe-market/README.md +176 -0
- package/dist/content/examples/warframe-market/listing.json +19 -0
- package/dist/content/examples/warframe-market/locales/en.json +44 -0
- package/dist/content/examples/warframe-market/locales/fr.json +44 -0
- package/dist/content/examples/warframe-market/logic.ts +1265 -0
- package/dist/content/examples/warframe-market/manifest.json +92 -0
- package/dist/content/examples/warframe-market/package.json +16 -0
- package/dist/content/examples/warframe-market/style.ocss +422 -0
- package/dist/content/examples/warframe-market/submission.json +24 -0
- package/dist/content/examples/warframe-market/tests/bounds.scenario.json +60 -0
- package/dist/content/examples/warframe-market/tests/cached.scenario.json +70 -0
- package/dist/content/examples/warframe-market/tests/detail.scenario.json +251 -0
- package/dist/content/examples/warframe-market/tests/errors.scenario.json +105 -0
- package/dist/content/examples/warframe-market/tests/fixtures.json +295 -0
- package/dist/content/examples/warframe-market/tests/load-logic.mjs +22 -0
- package/dist/content/examples/warframe-market/tests/logic.test.mjs +505 -0
- package/dist/content/examples/warframe-market/tests/no-clipboard.scenario.json +104 -0
- package/dist/content/examples/warframe-market/tests/passive.scenario.json +87 -0
- package/dist/content/examples/warframe-market/tests/preview.scenario.json +146 -0
- package/dist/content/examples/warframe-market/tests/refresh.scenario.json +56 -0
- package/dist/content/examples/warframe-market/tests/refused.scenario.json +74 -0
- package/dist/content/examples/warframe-market/tests/render.scenario.json +210 -0
- package/dist/content/examples/warframe-market/tests/search.scenario.json +189 -0
- package/dist/content/examples/warframe-market/tests/unavailable.scenario.json +54 -0
- package/dist/content/examples/warframe-market/tsconfig.json +16 -0
- package/dist/content/examples/warframe-market/view.ocml +116 -0
- package/dist/content/examples/weather/LICENSE +20 -0
- package/dist/content/examples/weather/listing.json +10 -0
- package/dist/content/examples/weather/locales/en.json +9 -0
- package/dist/content/examples/weather/locales/fr.json +9 -0
- package/dist/content/examples/weather/logic.ts +62 -0
- package/dist/content/examples/weather/manifest.json +51 -0
- package/dist/content/examples/weather/package.json +15 -0
- package/dist/content/examples/weather/style.ocss +29 -0
- package/dist/content/examples/weather/submission.json +17 -0
- package/dist/content/examples/weather/tsconfig.json +16 -0
- package/dist/content/examples/weather/view.ocml +12 -0
- package/dist/content/index.json +3705 -0
- package/dist/content/reference/errors.json +1924 -0
- package/dist/content/reference/limits.json +1154 -0
- package/dist/content/reference/manifest.md +223 -0
- package/dist/content/reference/permissions.json +413 -0
- package/dist/content/templates/blank/locales/en.json +3 -0
- package/dist/content/templates/blank/locales/fr.json +3 -0
- package/dist/content/templates/blank/logic.ts +7 -0
- package/dist/content/templates/blank/manifest.json +16 -0
- package/dist/content/templates/blank/style.ocss +10 -0
- package/dist/content/templates/blank/tests/example.scenario.json +10 -0
- package/dist/content/templates/blank/view.ocml +6 -0
- package/dist/content/templates/chart/locales/en.json +3 -0
- package/dist/content/templates/chart/locales/fr.json +3 -0
- package/dist/content/templates/chart/logic.ts +27 -0
- package/dist/content/templates/chart/manifest.json +16 -0
- package/dist/content/templates/chart/style.ocss +27 -0
- package/dist/content/templates/chart/tests/example.scenario.json +10 -0
- package/dist/content/templates/chart/view.ocml +10 -0
- package/dist/content/templates/counter/locales/en.json +4 -0
- package/dist/content/templates/counter/locales/fr.json +4 -0
- package/dist/content/templates/counter/logic.ts +20 -0
- package/dist/content/templates/counter/manifest.json +16 -0
- package/dist/content/templates/counter/style.ocss +26 -0
- package/dist/content/templates/counter/tests/example.scenario.json +11 -0
- package/dist/content/templates/counter/view.ocml +13 -0
- package/dist/content/templates/list/locales/en.json +8 -0
- package/dist/content/templates/list/locales/fr.json +8 -0
- package/dist/content/templates/list/logic.ts +35 -0
- package/dist/content/templates/list/manifest.json +16 -0
- package/dist/content/templates/list/style.ocss +42 -0
- package/dist/content/templates/list/tests/example.scenario.json +10 -0
- package/dist/content/templates/list/view.ocml +17 -0
- package/dist/content/templates/shared/LICENSE +20 -0
- package/dist/content/templates/shared/package.json +14 -0
- package/dist/content/templates/shared/tsconfig.json +16 -0
- package/dist/content.js +68 -0
- package/dist/env.js +156 -0
- package/dist/fingerprint.js +32 -0
- package/dist/hidden.js +47 -0
- package/dist/ids.js +27 -0
- package/dist/index.js +82 -0
- package/dist/knowledge.js +222 -0
- package/dist/npm.js +149 -0
- package/dist/prompts.js +47 -0
- package/dist/resources.js +82 -0
- package/dist/run.js +120 -0
- package/dist/server.js +43 -0
- package/dist/session.js +205 -0
- package/dist/sources.js +218 -0
- package/dist/text.js +80 -0
- package/dist/texts.js +44 -0
- package/dist/tools/audit.js +105 -0
- package/dist/tools/build.js +453 -0
- package/dist/tools/common.js +122 -0
- package/dist/tools/docs.js +196 -0
- package/dist/tools/preview.js +87 -0
- package/dist/tools/project.js +183 -0
- package/dist/tools/setup.js +146 -0
- package/dist/tools/submission.js +369 -0
- package/dist/version.js +3 -0
- package/npm-shrinkwrap.json +402 -0
- package/package.json +50 -4
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# Twitch chat
|
|
2
|
+
|
|
3
|
+
`com.playervox.overcrow.twitch.chat` — the chat of one public Twitch
|
|
4
|
+
channel you choose, over the game. In Interactive mode you pick the
|
|
5
|
+
channel, keep favorites, scroll the history, reply and send messages; in
|
|
6
|
+
Passive mode the last messages show and fade out. OverCrow holds your
|
|
7
|
+
Twitch account, the connection, the channel and the favorites: the widget
|
|
8
|
+
shows what OverCrow sends it and asks for the rest. A built-in of OverCrow,
|
|
9
|
+
written against the public `@overcrow/sdk` and packaged with
|
|
10
|
+
`overcrow-widget` like any creator's widget. MIT.
|
|
11
|
+
|
|
12
|
+
## What it shows
|
|
13
|
+
|
|
14
|
+
A header row, always: a chat icon, the channel (`#juniper_plays`, or
|
|
15
|
+
"Twitch" without one) and a status dot whose label, also its tooltip, says
|
|
16
|
+
the connection in words. In Interactive mode a joined channel adds the
|
|
17
|
+
favorite star and the "Change channel" and "Disconnect channel" buttons.
|
|
18
|
+
|
|
19
|
+
| State | Shows (EN / FR) |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| Waiting for OverCrow's first answer | the header alone, a grey dot: "INACTIVE" / "INACTIF" |
|
|
22
|
+
| No channel, Interactive mode | the channel selector: a field "Channel name" / "Nom de la chaîne", "Join chat" / "Rejoindre", the favorites under "Favorites" / "Favoris"; dot "DISCONNECTED" / "DÉCONNECTÉ" |
|
|
23
|
+
| No channel, Passive mode | "No channel selected" / "Aucune chaîne sélectionnée" |
|
|
24
|
+
| Connecting | an amber dot, "CONNECTING" / "CONNEXION EN COURS"; the message field waits: "Waiting for chat…" / "En attente du chat…" |
|
|
25
|
+
| Joined | a green dot, "CONNECTED" / "CONNECTÉ"; the history; the field "Send a message…" / "Envoyer un message…" and "Send" / "Envoyer" |
|
|
26
|
+
| Joined, nothing yet | Interactive: "No messages yet" / "Aucun message pour le moment"; Passive: "No recent messages" / "Aucun message récent" |
|
|
27
|
+
| Reconnecting | an amber dot, "RECONNECTING" / "RECONNEXION"; the history stays, the field waits |
|
|
28
|
+
| The join failed | a red dot and its label under the header: "CHANNEL UNAVAILABLE" / "CHAÎNE INDISPONIBLE", "CONNECTION ERROR" / "ERREUR DE CONNEXION", "TWITCH ERROR" / "ERREUR TWITCH", or "Another widget is using Twitch chat" / "Un autre widget utilise le chat Twitch" |
|
|
29
|
+
| Scrolled away from the end | a button, "1 new message" / "1 nouveau message", "{n} new messages" / "{n} nouveaux messages" |
|
|
30
|
+
| Messages left out of a fast chat | a row, "1 message not shown" / "1 message non affiché", "{n} messages not shown" / "{n} messages non affichés" |
|
|
31
|
+
| A channel or favorite change failed | under the header, in Interactive mode: "Twitch is busy. Try again." / "Twitch est occupé. Réessayez.", "Could not save Twitch widget settings." / "Impossible d’enregistrer les réglages du widget Twitch.", "Favorite channel limit reached." / "Nombre maximal de chaînes favorites atteint." |
|
|
32
|
+
| OverCrow's chat source failed | "Twitch is temporarily unavailable. Retrying automatically." / "Twitch est temporairement indisponible. Nouvelle tentative automatique."; the widget asks again 5 s later |
|
|
33
|
+
| No Twitch account, a sign-in in progress, an expired session | OverCrow's own account panel, over the widget, in both modes (see [Permissions](#permissions)) |
|
|
34
|
+
| No permission to read | "Allow access to Twitch chat in the Control Center." / "Autorisez l’accès au chat Twitch dans le Centre de contrôle.": the widget asks OverCrow nothing |
|
|
35
|
+
|
|
36
|
+
The size is the one you set, 420 × 360 px by default, from 160 × 24 px to
|
|
37
|
+
900 × 900 px: the history takes what the other rows leave, and a channel
|
|
38
|
+
name too long for the header ends with an ellipsis.
|
|
39
|
+
|
|
40
|
+
## The channel and the favorites
|
|
41
|
+
|
|
42
|
+
- **Join.** Type a channel in the selector and press Enter or "Join chat".
|
|
43
|
+
A name is accepted as Twitch writes a login: spaces around it and a
|
|
44
|
+
leading `#` are dropped, upper case becomes lower case, and what is left
|
|
45
|
+
is 1 to 25 ASCII letters, digits or `_`. The field takes 26 characters
|
|
46
|
+
(the `#` and 25 more). Anything else leaves "Join chat" off, and Enter
|
|
47
|
+
joins nothing.
|
|
48
|
+
- **Favorites.** Each favorite is a chip in the selector: a click joins it.
|
|
49
|
+
Three rows of chips show; more scroll in that height.
|
|
50
|
+
The star of the header adds the current channel to the favorites or
|
|
51
|
+
removes it ("Add current channel to favorites" / "Ajouter la chaîne
|
|
52
|
+
actuelle aux favoris", "Remove current channel from favorites" / "Retirer
|
|
53
|
+
la chaîne actuelle des favoris"); it is yellow for a favorite. OverCrow
|
|
54
|
+
keeps at most 20: beyond, the star of another channel takes no click and
|
|
55
|
+
says "Favorite channel limit reached". Passive mode shows the star of a
|
|
56
|
+
favorite channel, without a button.
|
|
57
|
+
- **Change channel** opens the selector over the chat, which stays until
|
|
58
|
+
another channel is joined, and closes it again.
|
|
59
|
+
- **Disconnect channel** leaves: OverCrow forgets the channel.
|
|
60
|
+
|
|
61
|
+
Each of these is one call to OverCrow on your gesture (`twitch.chat.join`,
|
|
62
|
+
`twitch.chat.favorite`, `twitch.chat.leave`). The widget stores nothing:
|
|
63
|
+
OverCrow remembers the channel and the favorites of this widget, joins the
|
|
64
|
+
channel again when the widget starts, and tells the widget the channel,
|
|
65
|
+
its state and the favorites through the subscription. What the widget
|
|
66
|
+
shows is what OverCrow last said, never what was typed. The selector's
|
|
67
|
+
field is OverCrow's to edit: a selector that starts over is a new one,
|
|
68
|
+
with an empty field.
|
|
69
|
+
|
|
70
|
+
The channel and the favorites are this widget's own: another widget
|
|
71
|
+
allowed to read Twitch chat has its own, and nothing it does changes
|
|
72
|
+
these. OverCrow connects to one chat at a time, the one joined last: a
|
|
73
|
+
widget whose channel is not that one keeps its channel and its favorites,
|
|
74
|
+
shows "Another widget is using Twitch chat", and gets the chat back when
|
|
75
|
+
the other leaves or stops, or when you join from it again.
|
|
76
|
+
|
|
77
|
+
## The history and the pace of the chat
|
|
78
|
+
|
|
79
|
+
Each line is the author's name, in bold and in their Twitch colour, then
|
|
80
|
+
the message: text and emotes, as tall as the line and centred on it, each
|
|
81
|
+
with its name as accessible label. OverCrow keeps a colour readable on the panel of the
|
|
82
|
+
current theme (a very dark name is lightened on a dark panel, a very light
|
|
83
|
+
one darkened on a light panel); an author without a colour is grey. A long
|
|
84
|
+
message wraps.
|
|
85
|
+
|
|
86
|
+
- The history keeps the last 200 messages, and fewer when they are long:
|
|
87
|
+
a message has at most 16 runs of text and emotes, and the rows together
|
|
88
|
+
stay within a budget of scene nodes, the oldest leaving first.
|
|
89
|
+
- The list follows its end. Scroll up and it stops following: new messages
|
|
90
|
+
are then counted on the "N new messages" button, which returns to the
|
|
91
|
+
latest; so does scrolling back to the end. This is the `list`'s
|
|
92
|
+
`stick-to-end` attribute and its `stick` event.
|
|
93
|
+
- **OverCrow sends the chat as deltas, at most one every 100 ms**: the new
|
|
94
|
+
messages to append, messages that changed (they replace the message of
|
|
95
|
+
the same ID where it stands) and the IDs of removed ones, which leave at
|
|
96
|
+
once: moderation is never left out. After subscribing, after a change of
|
|
97
|
+
channel or account and when the widget is shown again, one update
|
|
98
|
+
carries the whole list instead.
|
|
99
|
+
- **A chat faster than that is sampled.** OverCrow then leaves messages
|
|
100
|
+
out and says how many: the widget shows "N messages not shown" where
|
|
101
|
+
they would have been, and counts them among the new messages. Two such
|
|
102
|
+
rows in a row are one. Nothing is sent to a hidden widget.
|
|
103
|
+
|
|
104
|
+
## Replies
|
|
105
|
+
|
|
106
|
+
A message that answers another shows one line of what it answers above it
|
|
107
|
+
("Author: text", cut with an ellipsis), behind a rail. In Interactive mode,
|
|
108
|
+
with the permission to send, each message has a reply icon at the end of
|
|
109
|
+
its first line, visible under the pointer or with the keyboard on it
|
|
110
|
+
("Reply to {name}" / "Répondre à {name}"). It makes that message the target of the next send: "Replying to
|
|
111
|
+
{name}" / "Réponse à {name}" shows above the field, with a button to cancel
|
|
112
|
+
("Cancel reply" / "Annuler la réponse"). The target goes with the accepted
|
|
113
|
+
message, stays when a message is refused, and is dropped when its message
|
|
114
|
+
leaves the history.
|
|
115
|
+
|
|
116
|
+
## The composer
|
|
117
|
+
|
|
118
|
+
One line, at most 500 characters, and "Send".
|
|
119
|
+
|
|
120
|
+
- **The form is OverCrow's.** The message field is the host-owned control
|
|
121
|
+
of a `form` bound to the `twitch.chat.send` intent: the view gives it no
|
|
122
|
+
`value`, and the logic cannot write a character in it nor submit it.
|
|
123
|
+
OverCrow tells the logic the text through the field's `input` event, so
|
|
124
|
+
that "Send" is on only when there is something to send.
|
|
125
|
+
- **Sending** takes your gesture: Enter in the field or a click on "Send".
|
|
126
|
+
OverCrow sends the text of its own field, with the reply target as the
|
|
127
|
+
form's `target`, and tells the widget the outcome in the form's `submit`
|
|
128
|
+
event. Nothing is sent from an empty field or from spaces, and one
|
|
129
|
+
message is sent at a time: until OverCrow answers, the field still holds
|
|
130
|
+
the message, and Enter or "Send" sends nothing more.
|
|
131
|
+
- **OverCrow empties the field once the message is accepted**, and keeps
|
|
132
|
+
it otherwise, for another try.
|
|
133
|
+
- **There is no local echo.** A sent message shows in the history when
|
|
134
|
+
OverCrow delivers it, like any other. Meanwhile "sending…" / "envoi…"
|
|
135
|
+
shows beside the field; a refused message leaves "not sent" / "non
|
|
136
|
+
envoyé" there and its reason above the field:
|
|
137
|
+
|
|
138
|
+
| Refusal | Message (EN / FR) |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| Too many messages (OverCrow allows 20 per 30 s) | "Too many messages. Wait a moment, then try again." / "Trop de messages. Attendez un instant, puis réessayez." |
|
|
141
|
+
| The chat does not take this account's messages | "This chat does not accept your messages right now." / "Ce chat n’accepte pas vos messages pour le moment." |
|
|
142
|
+
| Anything else | "Message was not accepted. Try again." / "Le message a été refusé. Réessayez." |
|
|
143
|
+
| The send was abandoned before it left | "Message was not sent. Try again." / "Le message n’a pas été envoyé. Réessayez." |
|
|
144
|
+
|
|
145
|
+
Should OverCrow give no answer at all, the widget says "Message was not
|
|
146
|
+
accepted. Try again." after 40 s.
|
|
147
|
+
- **The draft is kept by OverCrow** while its form stays in the view: in
|
|
148
|
+
Passive mode and while the widget is hidden between two games (the form
|
|
149
|
+
is hidden, not removed), under the channel selector, and while
|
|
150
|
+
OverCrow's chat source is failing. The form's key is the chat's
|
|
151
|
+
`generation`, which changes with the channel or the account: another
|
|
152
|
+
channel is another form, with an empty field. A draft does not outlive
|
|
153
|
+
OverCrow.
|
|
154
|
+
|
|
155
|
+
OverCrow's field gives you the caret, the selection, copy, cut and paste
|
|
156
|
+
through OverCrow, and input methods (IME). Escape is OverCrow's: it leaves
|
|
157
|
+
Interactive mode, and the draft stays.
|
|
158
|
+
|
|
159
|
+
## Passive mode and the fade
|
|
160
|
+
|
|
161
|
+
Passive mode shows the last 12 messages younger than the lifetime, without
|
|
162
|
+
any control: no selector, no star button, no reply icon, no composer, and
|
|
163
|
+
no row for messages left out. Clicks go through to the game.
|
|
164
|
+
|
|
165
|
+
A message is opaque until two thirds of its lifetime, then fades to nothing
|
|
166
|
+
over the last third, and leaves. `receivedAt`, the time OverCrow received
|
|
167
|
+
the message, gives its age, also after the widget was hidden. The fade is
|
|
168
|
+
stepped: the logic gives a fading row one of 32 opacity classes, one level
|
|
169
|
+
per step (a 32nd of the fade: 313 ms for the default 30 s, never under
|
|
170
|
+
100 ms). Each step is one frame; the style has no transition, which would
|
|
171
|
+
have OverCrow draw a frame at every refresh for as long as a message
|
|
172
|
+
fades. One timer drives it: it sleeps until the first message starts to
|
|
173
|
+
fade, ticks once per step while one fades, and does not exist when nothing
|
|
174
|
+
shows.
|
|
175
|
+
Interactive mode keeps the whole history, opaque, and runs no timer.
|
|
176
|
+
|
|
177
|
+
## Menu
|
|
178
|
+
|
|
179
|
+
| Row | Type | Default |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| Message lifetime in Passive (s) / Durée des messages en mode passif (s) | slider `passive-lifetime`, 5 to 120 s | 30 |
|
|
182
|
+
|
|
183
|
+
## Permissions
|
|
184
|
+
|
|
185
|
+
- `twitch.chat.read`: join, read and leave the chat of a channel, and keep
|
|
186
|
+
favorite channels. Sensitive.
|
|
187
|
+
- `twitch.chat.compose`: send a message, only through the host-bound form.
|
|
188
|
+
Sensitive. Without it the widget shows the chat with its channel
|
|
189
|
+
controls, and no composer nor reply icon.
|
|
190
|
+
|
|
191
|
+
As sensitive capabilities rule out the network and the clipboard, the
|
|
192
|
+
widget declares neither, and no storage: it reaches Twitch only through
|
|
193
|
+
OverCrow and keeps nothing.
|
|
194
|
+
|
|
195
|
+
**The Twitch account is OverCrow's.** The widget never sees the account's
|
|
196
|
+
name, a sign-in code or a token. Without a session, during a sign-in and
|
|
197
|
+
after a session expired, OverCrow draws its own account panel over the
|
|
198
|
+
widget, in both modes, and no input reaches the widget; the sign-in itself
|
|
199
|
+
happens there and in your browser. Under the panel the widget only says
|
|
200
|
+
"Twitch is disconnected" / "Twitch est déconnecté" or "Twitch connection
|
|
201
|
+
pending" / "Connexion Twitch en attente". While OverCrow holds a session it
|
|
202
|
+
cannot check and retries, it adds its notice at the bottom of the widget.
|
|
203
|
+
|
|
204
|
+
## Tests
|
|
205
|
+
|
|
206
|
+
- `tests/logic.test.mjs`, `tests/refused.test.mjs`,
|
|
207
|
+
`tests/read-only.test.mjs`: the logic on `@overcrow/sdk/testing`
|
|
208
|
+
(`node --test tests/*.test.mjs`): channel names, the deltas (append,
|
|
209
|
+
replace, remove, reset, messages left out), the history's two bounds,
|
|
210
|
+
the unread count, a change of generation, the reply target, the fade's
|
|
211
|
+
levels, steps and single timer, the send cycle and each refusal, the
|
|
212
|
+
channel and favorite calls and their refusals, every status, the retry of
|
|
213
|
+
a failed subscription, the missing grants, the messages of both
|
|
214
|
+
languages.
|
|
215
|
+
- Scenarios, played in OverCrow's headless runtime
|
|
216
|
+
(`overcrow-widget test --runtime …`), with their reference images in
|
|
217
|
+
`tests/reference/`. The emotes are synthetic images drawn by
|
|
218
|
+
`tests/assets/generate.mjs`; authors and channels are invented.
|
|
219
|
+
|
|
220
|
+
| Scenario | Covers |
|
|
221
|
+
| --- | --- |
|
|
222
|
+
| `states` | Interactive mode: waiting, the selector without and with favorites, connecting, joined and empty, joined, reconnecting and its tooltip; dark English and light French, 100 % and 150 %, 180 px wide |
|
|
223
|
+
| `passive` | Passive mode: waiting, no channel, connecting, joined and empty, the last 12 of 15 messages; light French, 150 %, 180 px wide; clicks and keys reach nothing |
|
|
224
|
+
| `failures` | each failed join, in both modes and languages, with and without history; joined again |
|
|
225
|
+
| `unavailable` | the source failed and came back 5 s later, in both modes and languages; the draft kept |
|
|
226
|
+
| `render` | coloured authors (a very dark and a very light colour), no colour, emotes of three shapes, a wrapped message, a reply, a message of 16 runs, the reply icon and its tooltip; both themes and languages, 100 % and 150 %, 180 px wide, Passive mode |
|
|
227
|
+
| `fade` | the Passive fade in virtual time: opaque, half-way, nearly gone, gone; hidden then shown; a new message; the history in Interactive mode |
|
|
228
|
+
| `lifetime` | the menu row at 120 s, 5 s and 30 s |
|
|
229
|
+
| `burst` | deltas 100 ms apart: messages left out, two such rows merged, a replacement in place, removals, sixty messages in two seconds, a reset; no such row in Passive mode |
|
|
230
|
+
| `unread` | scrolled away, the count (messages left out included, replacements and removals not), the button, scrolling back, a reset |
|
|
231
|
+
| `channel` | an invalid name, 26 characters, Enter and the button, the selector over the chat, a favorite's chip, leaving, each with its call |
|
|
232
|
+
| `favorites` | the star and its calls, its tooltips, the limit of 20, the 20 chips, the star in Passive mode |
|
|
233
|
+
| `channel-refused` | a join, a favorite and a leave refused: busy, not saved, favorites full; English and French |
|
|
234
|
+
| `send` | nothing sent from an empty field or spaces; Enter and the button, with what OverCrow sent; the field emptied once accepted |
|
|
235
|
+
| `reply` | the reply target, cancelled, kept by a refusal, gone with the accepted message, dropped with its message; English and French, 180 px wide |
|
|
236
|
+
| `send-refused` | too fast, a chat that does not take the account's messages, not accepted, then accepted; no answer for 40 s, and nothing more sent meanwhile; English and French |
|
|
237
|
+
| `draft` | a draft through Passive mode, a hidden widget and the selector; another channel empties it |
|
|
238
|
+
| `account` | OverCrow's account panel for a missing, pending and expired session and its offline notice, in both modes, with the wrapper |
|
|
239
|
+
| `frame` | the widget in OverCrow's wrapper |
|
|
240
|
+
| `read-only` | the read grant alone: the chat, the channel controls, nothing that sends |
|
|
241
|
+
| `refused` | no grant: no call |
|
|
242
|
+
|
|
243
|
+
A scenario can expect the fields of a submitted form, not its `target`:
|
|
244
|
+
the unit tests cover the reply target the form carries.
|
|
245
|
+
|
|
246
|
+
## Cost
|
|
247
|
+
|
|
248
|
+
Measured on 2026-10-01 with OverCrow's release build, on an AMD Ryzen 7
|
|
249
|
+
5800X3D Linux workstation and in a Windows 11 virtual machine (2 vCPU),
|
|
250
|
+
over a synthetic chat: 200 messages, each a coloured author, text, one of
|
|
251
|
+
eight emotes and more text that wraps, at the default size.
|
|
252
|
+
|
|
253
|
+
| | Linux | Windows (VM) |
|
|
254
|
+
| --- | --- | --- |
|
|
255
|
+
| Widget start, warm, into the overlay's runtime, 200 messages | 10.0–10.1 ms (p50), 11.2 ms at most | VM ready in 17.0–20.8 ms (p50) |
|
|
256
|
+
| VM memory, Interactive mode, 200 messages | 2.6 MiB private; 3.2 MiB while the chat turns over | — |
|
|
257
|
+
| VM memory, Passive mode | 1.7 MiB private, 1.9 MiB PSS | 1.71–1.73 MiB private working set, 2.20–2.23 MiB private commit |
|
|
258
|
+
| Private memory in all (VM, sandbox helpers, overlay share), Interactive mode | 18–21 MB with 200 messages held, 23–26 MB while they turn over | — |
|
|
259
|
+
| Private memory in all, Passive mode | 9–12 MB | — |
|
|
260
|
+
| CPU at rest, 200 messages held | 0.05 % of one core, no frame | — |
|
|
261
|
+
| 1 message a second, Interactive mode | overlay 0.15–0.17 % of one core, VM 0.25–0.28 %; one frame per message, 1.1 ms (p95) | — |
|
|
262
|
+
| 10 messages a second | overlay 1.1 %, VM 2.2 %; ten frames a second, 1.1 ms (p95) | — |
|
|
263
|
+
| 50 messages a second | overlay 1.4–1.5 %, VM 2.3–2.5 %; ten frames a second, 1.3–1.4 ms (p95), 2.8 ms at most | — |
|
|
264
|
+
| 50 messages a second, Passive mode | overlay 1.0–1.1 %, VM 0.6–0.7 %; ten frames a second, 0.8 ms (p95) | — |
|
|
265
|
+
| Passive mode, messages fading (one every 5 s) | overlay 0.13 %, VM 0.07 %; 2 to 3 frames a second | — |
|
|
266
|
+
| Hidden, 50 messages a second | 0.10–0.12 % of one core, one frame in a minute, the VM idle | — |
|
|
267
|
+
|
|
268
|
+
OverCrow sends the chat at most every 100 ms: an update is one turn of the
|
|
269
|
+
widget's logic and one frame, so fifty messages a second cost what ten do,
|
|
270
|
+
and nothing is drawn while nothing arrives. Each update is read before the
|
|
271
|
+
next is sent; a chat beyond 200 messages a second would be sampled. A
|
|
272
|
+
frame of the chat stays under OverCrow's 2 ms goal at the 95th percentile;
|
|
273
|
+
the longest frame of a burst took 2.8 ms. The private memory is above
|
|
274
|
+
OverCrow's 8 MB goal per widget, around its 20 MB threshold in Interactive
|
|
275
|
+
mode, where OverCrow lays out 200 messages, and above it by up to 6 MB
|
|
276
|
+
while they turn over; far under the 80 MB ceiling. The Passive fade is 32
|
|
277
|
+
steps on one timer: a first version with a style transition had OverCrow
|
|
278
|
+
draw 43 frames a second while a message faded, for the same picture. The
|
|
279
|
+
egui widget it replaces painted in the overlay's own process at every
|
|
280
|
+
frame (0.8–1.0 ms with 200 messages) and every 100 ms in Passive mode;
|
|
281
|
+
OverCrow connected to the chat whenever that widget was enabled, and now
|
|
282
|
+
only while this widget subscribes. Scenarios render the same images on
|
|
283
|
+
Linux and Windows, pixel for pixel.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "PlayerVox",
|
|
3
|
+
"spdxLicense": "MIT",
|
|
4
|
+
"sourceUrl": "https://github.com/Valhallab/playervox-overcrow-releases/tree/main/widgets/twitch-chat",
|
|
5
|
+
"preview": "assets/preview.png",
|
|
6
|
+
"defaultLocale": "en",
|
|
7
|
+
"localizations": [
|
|
8
|
+
{
|
|
9
|
+
"locale": "en",
|
|
10
|
+
"name": "Twitch chat",
|
|
11
|
+
"description": "Read and send messages in a public Twitch chat you choose: your favorite channels, the scrolling history with emotes and replies in Interactive mode, the last messages fading out in Passive mode. Needs your Twitch account."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"locale": "fr",
|
|
15
|
+
"name": "Chat Twitch",
|
|
16
|
+
"description": "Lisez et envoyez des messages dans le chat Twitch public de votre choix : vos chaînes favorites, l’historique défilant avec emotes et réponses en mode interactif, les derniers messages qui s’effacent en mode passif. Nécessite votre compte Twitch."
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"label": "Twitch chat",
|
|
3
|
+
"twitch": "Twitch",
|
|
4
|
+
"no-permission": "Allow access to Twitch chat in the Control Center.",
|
|
5
|
+
"unavailable": "Twitch is temporarily unavailable. Retrying automatically.",
|
|
6
|
+
"signed-out": "Twitch is disconnected",
|
|
7
|
+
"pending": "Twitch connection pending",
|
|
8
|
+
"inactive": "INACTIVE",
|
|
9
|
+
"disconnected": "DISCONNECTED",
|
|
10
|
+
"connecting": "CONNECTING",
|
|
11
|
+
"connected": "CONNECTED",
|
|
12
|
+
"reconnecting": "RECONNECTING",
|
|
13
|
+
"channel-unavailable": "CHANNEL UNAVAILABLE",
|
|
14
|
+
"connection-error": "CONNECTION ERROR",
|
|
15
|
+
"twitch-error": "TWITCH ERROR",
|
|
16
|
+
"limit": "Another widget is using Twitch chat",
|
|
17
|
+
"channel-name": "Channel name",
|
|
18
|
+
"join": "Join chat",
|
|
19
|
+
"favorites": "Favorites",
|
|
20
|
+
"favorite-channel": "Favorite channel",
|
|
21
|
+
"favorite": "Favorite #{channel}",
|
|
22
|
+
"unfavorite": "Unfavorite #{channel}",
|
|
23
|
+
"favorite-add": "Add current channel to favorites",
|
|
24
|
+
"favorite-remove": "Remove current channel from favorites",
|
|
25
|
+
"favorite-limit": "Favorite channel limit reached",
|
|
26
|
+
"change-channel": "Change channel",
|
|
27
|
+
"leave-channel": "Disconnect channel",
|
|
28
|
+
"no-channel": "No channel selected",
|
|
29
|
+
"no-messages": "No messages yet",
|
|
30
|
+
"no-recent": "No recent messages",
|
|
31
|
+
"new-message": "1 new message",
|
|
32
|
+
"new-messages": "{count} new messages",
|
|
33
|
+
"skipped-one": "1 message not shown",
|
|
34
|
+
"skipped": "{count} messages not shown",
|
|
35
|
+
"reply": "Reply",
|
|
36
|
+
"reply-to": "Reply to {name}",
|
|
37
|
+
"replying-to": "Replying to {name}",
|
|
38
|
+
"cancel-reply": "Cancel reply",
|
|
39
|
+
"message-label": "Message",
|
|
40
|
+
"send-hint": "Send a message…",
|
|
41
|
+
"waiting-hint": "Waiting for chat…",
|
|
42
|
+
"send": "Send",
|
|
43
|
+
"sending": "sending…",
|
|
44
|
+
"not-sent": "not sent",
|
|
45
|
+
"error-not-accepted": "Message was not accepted. Try again.",
|
|
46
|
+
"error-not-sent": "Message was not sent. Try again.",
|
|
47
|
+
"error-too-fast": "Too many messages. Wait a moment, then try again.",
|
|
48
|
+
"error-restricted": "This chat does not accept your messages right now.",
|
|
49
|
+
"error-busy": "Twitch is busy. Try again.",
|
|
50
|
+
"error-settings": "Could not save Twitch widget settings.",
|
|
51
|
+
"error-favorite-limit": "Favorite channel limit reached."
|
|
52
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"label": "Chat Twitch",
|
|
3
|
+
"twitch": "Twitch",
|
|
4
|
+
"no-permission": "Autorisez l’accès au chat Twitch dans le Centre de contrôle.",
|
|
5
|
+
"unavailable": "Twitch est temporairement indisponible. Nouvelle tentative automatique.",
|
|
6
|
+
"signed-out": "Twitch est déconnecté",
|
|
7
|
+
"pending": "Connexion Twitch en attente",
|
|
8
|
+
"inactive": "INACTIF",
|
|
9
|
+
"disconnected": "DÉCONNECTÉ",
|
|
10
|
+
"connecting": "CONNEXION EN COURS",
|
|
11
|
+
"connected": "CONNECTÉ",
|
|
12
|
+
"reconnecting": "RECONNEXION",
|
|
13
|
+
"channel-unavailable": "CHAÎNE INDISPONIBLE",
|
|
14
|
+
"connection-error": "ERREUR DE CONNEXION",
|
|
15
|
+
"twitch-error": "ERREUR TWITCH",
|
|
16
|
+
"limit": "Un autre widget utilise le chat Twitch",
|
|
17
|
+
"channel-name": "Nom de la chaîne",
|
|
18
|
+
"join": "Rejoindre",
|
|
19
|
+
"favorites": "Favoris",
|
|
20
|
+
"favorite-channel": "Chaîne favorite",
|
|
21
|
+
"favorite": "Ajouter #{channel} aux favoris",
|
|
22
|
+
"unfavorite": "Retirer #{channel} des favoris",
|
|
23
|
+
"favorite-add": "Ajouter la chaîne actuelle aux favoris",
|
|
24
|
+
"favorite-remove": "Retirer la chaîne actuelle des favoris",
|
|
25
|
+
"favorite-limit": "Nombre maximal de chaînes favorites atteint",
|
|
26
|
+
"change-channel": "Changer de chaîne",
|
|
27
|
+
"leave-channel": "Quitter la chaîne",
|
|
28
|
+
"no-channel": "Aucune chaîne sélectionnée",
|
|
29
|
+
"no-messages": "Aucun message pour le moment",
|
|
30
|
+
"no-recent": "Aucun message récent",
|
|
31
|
+
"new-message": "1 nouveau message",
|
|
32
|
+
"new-messages": "{count} nouveaux messages",
|
|
33
|
+
"skipped-one": "1 message non affiché",
|
|
34
|
+
"skipped": "{count} messages non affichés",
|
|
35
|
+
"reply": "Répondre",
|
|
36
|
+
"reply-to": "Répondre à {name}",
|
|
37
|
+
"replying-to": "Réponse à {name}",
|
|
38
|
+
"cancel-reply": "Annuler la réponse",
|
|
39
|
+
"message-label": "Message",
|
|
40
|
+
"send-hint": "Envoyer un message…",
|
|
41
|
+
"waiting-hint": "En attente du chat…",
|
|
42
|
+
"send": "Envoyer",
|
|
43
|
+
"sending": "envoi…",
|
|
44
|
+
"not-sent": "non envoyé",
|
|
45
|
+
"error-not-accepted": "Le message a été refusé. Réessayez.",
|
|
46
|
+
"error-not-sent": "Le message n’a pas été envoyé. Réessayez.",
|
|
47
|
+
"error-too-fast": "Trop de messages. Attendez un instant, puis réessayez.",
|
|
48
|
+
"error-restricted": "Ce chat n’accepte pas vos messages pour le moment.",
|
|
49
|
+
"error-busy": "Twitch est occupé. Réessayez.",
|
|
50
|
+
"error-settings": "Impossible d’enregistrer les réglages du widget Twitch.",
|
|
51
|
+
"error-favorite-limit": "Nombre maximal de chaînes favorites atteint."
|
|
52
|
+
}
|