diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 1f8f19b..bb28634 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -32,6 +32,10 @@ export default defineConfig({ logo: '/favicon.svg', nav: [ + { + text: 'Playground', + link: '/playground', + }, { text: 'Guide', activeMatch: '^/guide/', @@ -117,6 +121,7 @@ function sidebarPrimary(): DefaultTheme.SidebarItem[] { { text: 'Tooling', items: [ + { text: 'Playground', link: '/playground' }, { text: 'CLI Reference', link: '/cli/' }, { text: 'Tools & Playgrounds', link: '/ecosystem/tools-and-playgrounds' }, ], diff --git a/docs/.vitepress/theme/components/PlaygroundLayout.vue b/docs/.vitepress/theme/components/PlaygroundLayout.vue new file mode 100644 index 0000000..e9e6d68 --- /dev/null +++ b/docs/.vitepress/theme/components/PlaygroundLayout.vue @@ -0,0 +1,497 @@ + + + + + + + + Playground + Experiment with JSON to TOON encoding in real-time. + + + + + + + + {{ opt.label }} + + + + + + + + + + loadPreset((e.target as HTMLSelectElement).value as keyof typeof PRESETS)"> + + Load example... + + + Users + + + Config + + + Products + + + + + + + {{ hasCopiedUrl ? 'Copied!' : 'Share' }} + + + + + + + + + JSON Input + + {{ jsonTokens ?? '...' }} tokens + {{ jsonInput.length }} chars + + + + + + + + + + TOON Output + + −{{ tokenSavings.percent }}% + + + + {{ toonTokens ?? '...' }} tokens + {{ toonOutput.length }} chars + + + + + {{ toonOutput }} + + {{ error }} + + + + + + + + + diff --git a/docs/.vitepress/theme/components/VPInput.vue b/docs/.vitepress/theme/components/VPInput.vue new file mode 100644 index 0000000..5305d89 --- /dev/null +++ b/docs/.vitepress/theme/components/VPInput.vue @@ -0,0 +1,53 @@ + + + + + {{ label }} + + + + + + + diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index e7524b7..797185f 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -1,6 +1,8 @@ import type { Theme } from 'vitepress' import CopyOrDownloadAsMarkdownButtons from 'vitepress-plugin-llms/vitepress-components/CopyOrDownloadAsMarkdownButtons.vue' import DefaultTheme from 'vitepress/theme' +import PlaygroundLayout from './components/PlaygroundLayout.vue' +import VPInput from './components/VPInput.vue' import './vars.css' import './overrides.css' @@ -13,6 +15,8 @@ const config: Theme = { version: '3.0', } app.component('CopyOrDownloadAsMarkdownButtons', CopyOrDownloadAsMarkdownButtons) + app.component('PlaygroundLayout', PlaygroundLayout) + app.component('VPInput', VPInput) }, } diff --git a/docs/ecosystem/tools-and-playgrounds.md b/docs/ecosystem/tools-and-playgrounds.md index 058be20..4088c7b 100644 --- a/docs/ecosystem/tools-and-playgrounds.md +++ b/docs/ecosystem/tools-and-playgrounds.md @@ -1,10 +1,14 @@ # Tools & Playgrounds -Experiment with TOON format interactively using these community-built tools for token comparison, format conversion, and validation. +Experiment with TOON format interactively using these tools for token comparison, format conversion, and validation. ## Playgrounds -Experiment with TOON format interactively using these community-built tools for token comparison, format conversion, and validation: +### Official Playground + +The [TOON Playground](/playground) lets you convert JSON to TOON in real-time, compare token counts, and share your experiments via URL. + +### Community Playgrounds - [Format Tokenization Playground](https://www.curiouslychase.com/playground/format-tokenization-exploration) - [TOON Tools](https://toontools.vercel.app/) diff --git a/docs/index.md b/docs/index.md index f616147..828baf3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,17 +11,17 @@ hero: alt: TOON Logo actions: - theme: brand - text: Get Started + text: What is TOON? link: /guide/getting-started - theme: alt text: Benchmarks link: /guide/benchmarks + - theme: alt + text: Playground + link: /playground - theme: alt text: CLI link: /cli/ - - theme: alt - text: Spec v3.0 - link: /reference/spec features: - title: Token-Efficient & Accurate diff --git a/docs/package.json b/docs/package.json index 42f8248..ef7c118 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,6 +8,9 @@ "preview": "vitepress preview" }, "devDependencies": { + "@vueuse/core": "^14.1.0", + "gpt-tokenizer": "^3.4.0", + "lz-string": "^1.5.0", "markdown-it-mathjax3": "^4.3.2", "unocss": "^66.5.9", "vitepress": "^1.6.4", diff --git a/docs/playground.md b/docs/playground.md new file mode 100644 index 0000000..d457329 --- /dev/null +++ b/docs/playground.md @@ -0,0 +1,4 @@ +--- +layout: PlaygroundLayout +title: Playground +--- diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9645b55..1a25673 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -89,6 +89,15 @@ importers: docs: devDependencies: + '@vueuse/core': + specifier: ^14.1.0 + version: 14.1.0(vue@3.5.24(typescript@5.9.3)) + gpt-tokenizer: + specifier: ^3.4.0 + version: 3.4.0 + lz-string: + specifier: ^1.5.0 + version: 1.5.0 markdown-it-mathjax3: specifier: ^4.3.2 version: 4.3.2 @@ -1442,6 +1451,11 @@ packages: '@vueuse/core@12.8.2': resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==} + '@vueuse/core@14.1.0': + resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==} + peerDependencies: + vue: ^3.5.0 + '@vueuse/integrations@12.8.2': resolution: {integrity: sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==} peerDependencies: @@ -1486,9 +1500,17 @@ packages: '@vueuse/metadata@12.8.2': resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==} + '@vueuse/metadata@14.1.0': + resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==} + '@vueuse/shared@12.8.2': resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} + '@vueuse/shared@14.1.0': + resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==} + peerDependencies: + vue: ^3.5.0 + '@xmldom/xmldom@0.9.8': resolution: {integrity: sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==} engines: {node: '>=14.6'} @@ -2437,6 +2459,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -4829,6 +4855,13 @@ snapshots: transitivePeerDependencies: - typescript + '@vueuse/core@14.1.0(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.1.0 + '@vueuse/shared': 14.1.0(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + '@vueuse/integrations@12.8.2(change-case@5.4.4)(focus-trap@7.6.6)(typescript@5.9.3)': dependencies: '@vueuse/core': 12.8.2(typescript@5.9.3) @@ -4842,12 +4875,18 @@ snapshots: '@vueuse/metadata@12.8.2': {} + '@vueuse/metadata@14.1.0': {} + '@vueuse/shared@12.8.2(typescript@5.9.3)': dependencies: vue: 3.5.24(typescript@5.9.3) transitivePeerDependencies: - typescript + '@vueuse/shared@14.1.0(vue@3.5.24(typescript@5.9.3))': + dependencies: + vue: 3.5.24(typescript@5.9.3) + '@xmldom/xmldom@0.9.8': {} acorn-jsx@5.3.2(acorn@8.15.0): @@ -5888,6 +5927,8 @@ snapshots: lru-cache@10.4.3: {} + lz-string@1.5.0: {} + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5
Experiment with JSON to TOON encoding in real-time.
{{ toonOutput }}