Thomas G. Lopes commited on
Commit
79784ac
·
1 Parent(s): a379843

include heading & install instrs

Browse files
src/lib/components/InferencePlayground/InferencePlaygroundCodeSnippets.svelte CHANGED
@@ -15,6 +15,7 @@
15
  type GetInferenceSnippetReturn,
16
  type InferenceSnippetLanguage,
17
  } from "./inferencePlaygroundUtils";
 
18
 
19
  hljs.registerLanguage("javascript", javascript);
20
  hljs.registerLanguage("python", python);
@@ -24,16 +25,14 @@
24
 
25
  const dispatch = createEventDispatcher<{ closeCode: void }>();
26
 
27
- const lanuages = ["javascript", "python", "http"];
28
- type Language = (typeof lanuages)[number];
29
- const labelsByLanguage: Record<Language, string> = {
30
  javascript: "JavaScript",
31
  python: "Python",
32
  http: "cURL",
33
- };
 
34
 
35
- let selectedLanguage: Language = "javascript";
36
- let timeout: ReturnType<typeof setTimeout>;
37
  let showToken = false;
38
 
39
  $: tokenStr = getTokenStr(showToken);
@@ -53,13 +52,39 @@
53
  });
54
  }
55
 
56
- $: clientSnippetsByLang = {
57
  javascript: getSnippet({ lang: "js", tokenStr, conversation }),
58
  python: getSnippet({ lang: "python", tokenStr, conversation }),
59
  http: getSnippet({ lang: "curl", tokenStr, conversation }),
60
  } as Record<Language, GetInferenceSnippetReturn>;
61
 
62
- const selectedClientIdxByLang: Record<Language, number> = Object.fromEntries(lanuages.map(lang => [lang, 0]));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
  function getTokenStr(showToken: boolean) {
65
  if ($token.value && showToken) {
@@ -68,13 +93,30 @@
68
  return "YOUR_HF_TOKEN";
69
  }
70
 
71
- function highlight(code: string, language: Language) {
72
  return hljs.highlight(code, { language: language === "curl" ? "http" : language }).value;
73
  }
74
 
75
- onDestroy(() => {
76
- clearTimeout(timeout);
77
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  </script>
79
 
80
  <div class="px-2 pt-2">
@@ -82,11 +124,11 @@
82
  class="border-b border-gray-200 text-center text-sm font-medium text-gray-500 dark:border-gray-700 dark:text-gray-400"
83
  >
84
  <ul class="-mb-px flex flex-wrap">
85
- {#each Object.entries(labelsByLanguage) as [language, label]}
86
  <li>
87
  <button
88
- on:click={() => (selectedLanguage = language)}
89
- class="inline-block rounded-t-lg border-b-2 p-4 {language === selectedLanguage
90
  ? 'border-black text-black dark:border-blue-500 dark:text-blue-500'
91
  : 'border-transparent hover:border-gray-300 hover:text-gray-600 dark:hover:text-gray-300'}"
92
  aria-current="page">{label}</button
@@ -106,52 +148,62 @@
106
  </ul>
107
  </div>
108
 
109
- {#if (clientSnippetsByLang[selectedLanguage]?.length ?? 0) > 1}
110
  <div class="flex gap-x-2 px-2 pt-6">
111
- {#each clientSnippetsByLang[selectedLanguage] ?? [] as { client }, idx}
112
- {@const isActive = idx === selectedClientIdxByLang[selectedLanguage]}
113
  <button
114
  class="rounded-lg border px-1.5 py-0.5 text-sm leading-tight
115
  {isActive
116
  ? 'bg-black text-gray-100 dark:border-gray-500 dark:bg-gray-700 dark:text-white'
117
  : 'text-gray-500 hover:text-gray-600 dark:border-gray-600 dark:hover:text-gray-400'}"
118
- on:click={() => (selectedClientIdxByLang[selectedLanguage] = idx)}>{client}</button
119
  >
120
  {/each}
121
  </div>
122
  {/if}
123
 
124
- {#each clientSnippetsByLang[selectedLanguage] ?? [] as { language, content }, idx}
125
- {#if idx === selectedClientIdxByLang[selectedLanguage]}
126
- <div class="flex items-center justify-end px-2 pt-6 pb-4">
127
- <div class="flex items-center gap-x-4">
128
- <label class="flex items-center gap-x-1.5 text-sm select-none">
129
- <input type="checkbox" bind:checked={showToken} />
130
- <p class="leading-none">With token</p>
131
- </label>
132
- <button
133
- class="flex items-center gap-x-2 rounded-md border bg-white px-1.5 py-0.5 text-sm shadow-xs transition dark:border-gray-800 dark:bg-gray-800"
134
- on:click={e => {
135
- const el = e.currentTarget;
136
- el.classList.add("text-green-500");
137
- navigator.clipboard.writeText(content);
138
- if (timeout) {
139
- clearTimeout(timeout);
140
- }
141
- timeout = setTimeout(() => {
142
- el.classList.remove("text-green-500");
143
- }, 400);
144
- }}
145
- >
146
- <IconCopyCode classNames="text-xs" /> Copy code
147
- </button>
148
- </div>
149
  </div>
150
- <pre
151
- class="overflow-x-auto rounded-lg border border-gray-200/80 bg-white px-4 py-6 text-sm shadow-xs dark:border-gray-800 dark:bg-gray-800/50">{@html highlight(
152
- content,
153
- language ?? selectedLanguage
154
- )}</pre>
 
 
 
 
 
 
 
 
155
  {/if}
156
- {/each}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  </div>
 
15
  type GetInferenceSnippetReturn,
16
  type InferenceSnippetLanguage,
17
  } from "./inferencePlaygroundUtils";
18
+ import { keys, fromEntries, entries } from "$lib/utils/object";
19
 
20
  hljs.registerLanguage("javascript", javascript);
21
  hljs.registerLanguage("python", python);
 
25
 
26
  const dispatch = createEventDispatcher<{ closeCode: void }>();
27
 
28
+ const labelsByLanguage = {
 
 
29
  javascript: "JavaScript",
30
  python: "Python",
31
  http: "cURL",
32
+ } as const satisfies Record<string, string>;
33
+ type Language = keyof typeof labelsByLanguage;
34
 
35
+ let lang: Language = "javascript";
 
36
  let showToken = false;
37
 
38
  $: tokenStr = getTokenStr(showToken);
 
52
  });
53
  }
54
 
55
+ $: snippetsByLang = {
56
  javascript: getSnippet({ lang: "js", tokenStr, conversation }),
57
  python: getSnippet({ lang: "python", tokenStr, conversation }),
58
  http: getSnippet({ lang: "curl", tokenStr, conversation }),
59
  } as Record<Language, GetInferenceSnippetReturn>;
60
 
61
+ // { javascript: 0, python: 0, http: 0 } at first
62
+ const selectedSnippetIdxByLang: Record<Language, number> = fromEntries(
63
+ keys(labelsByLanguage).map(lang => {
64
+ return [lang, 0];
65
+ })
66
+ );
67
+ $: selectedSnippet = snippetsByLang[lang][selectedSnippetIdxByLang[lang]]!;
68
+
69
+ type InstallInstructions = {
70
+ title: string;
71
+ content: string;
72
+ };
73
+ $: installInstructions = (function getInstallInstructions() {
74
+ if (lang === "javascript") {
75
+ const toInstall = selectedSnippet.client.includes("hugging") ? "@huggingface/inference" : "openai";
76
+ return {
77
+ title: `Install ${toInstall}`,
78
+ content: `npm install --save ${toInstall}`,
79
+ };
80
+ } else if (lang === "python") {
81
+ const toInstall = selectedSnippet.client.includes("hugging") ? "huggingface_hub" : "openai";
82
+ return {
83
+ title: `Install the latest`,
84
+ content: `pip install --upgrade ${toInstall}`,
85
+ };
86
+ }
87
+ })();
88
 
89
  function getTokenStr(showToken: boolean) {
90
  if ($token.value && showToken) {
 
93
  return "YOUR_HF_TOKEN";
94
  }
95
 
96
+ function highlight(code: string, language: InferenceSnippetLanguage) {
97
  return hljs.highlight(code, { language: language === "curl" ? "http" : language }).value;
98
  }
99
 
100
+ function copy(el: HTMLElement, content: string) {
101
+ let timeout: Timer;
102
+
103
+ function onClick() {
104
+ el.classList.add("text-green-500");
105
+ navigator.clipboard.writeText(content);
106
+ clearTimeout(timeout);
107
+ timeout = setTimeout(() => {
108
+ el.classList.remove("text-green-500");
109
+ }, 400);
110
+ }
111
+ el.addEventListener("click", onClick);
112
+
113
+ return {
114
+ destroy() {
115
+ clearTimeout(timeout);
116
+ el.removeEventListener("click", onClick);
117
+ },
118
+ };
119
+ }
120
  </script>
121
 
122
  <div class="px-2 pt-2">
 
124
  class="border-b border-gray-200 text-center text-sm font-medium text-gray-500 dark:border-gray-700 dark:text-gray-400"
125
  >
126
  <ul class="-mb-px flex flex-wrap">
127
+ {#each entries(labelsByLanguage) as [language, label]}
128
  <li>
129
  <button
130
+ on:click={() => (lang = language)}
131
+ class="inline-block rounded-t-lg border-b-2 p-4 {lang === language
132
  ? 'border-black text-black dark:border-blue-500 dark:text-blue-500'
133
  : 'border-transparent hover:border-gray-300 hover:text-gray-600 dark:hover:text-gray-300'}"
134
  aria-current="page">{label}</button
 
148
  </ul>
149
  </div>
150
 
151
+ {#if (snippetsByLang[lang]?.length ?? 0) > 1}
152
  <div class="flex gap-x-2 px-2 pt-6">
153
+ {#each snippetsByLang[lang] ?? [] as { client }, idx}
154
+ {@const isActive = idx === selectedSnippetIdxByLang[lang]}
155
  <button
156
  class="rounded-lg border px-1.5 py-0.5 text-sm leading-tight
157
  {isActive
158
  ? 'bg-black text-gray-100 dark:border-gray-500 dark:bg-gray-700 dark:text-white'
159
  : 'text-gray-500 hover:text-gray-600 dark:border-gray-600 dark:hover:text-gray-400'}"
160
+ on:click={() => (selectedSnippetIdxByLang[lang] = idx)}>{client}</button
161
  >
162
  {/each}
163
  </div>
164
  {/if}
165
 
166
+ {#if installInstructions}
167
+ <div class="flex items-center justify-between px-2 pt-6 pb-4">
168
+ <h2 class="font-semibold">{installInstructions.title}</h2>
169
+ <div class="flex items-center gap-x-4">
170
+ <button
171
+ class="flex items-center gap-x-2 rounded-md border bg-white px-1.5 py-0.5 text-sm shadow-xs transition dark:border-gray-800 dark:bg-gray-800"
172
+ use:copy={selectedSnippet.content}
173
+ >
174
+ <IconCopyCode classNames="text-xs" /> Copy code
175
+ </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  </div>
177
+ </div>
178
+ <pre
179
+ class="overflow-x-auto rounded-lg border border-gray-200/80 bg-white px-4 py-6 text-sm shadow-xs dark:border-gray-800 dark:bg-gray-800/50">{@html highlight(
180
+ installInstructions.content,
181
+ selectedSnippet.language
182
+ )}</pre>
183
+ {/if}
184
+
185
+ <div class="flex items-center justify-between px-2 pt-6 pb-4">
186
+ {#if conversation.streaming}
187
+ <h2 class="font-semibold">Streaming API</h2>
188
+ {:else}
189
+ <h2 class="font-semibold">Non-Streaming API</h2>
190
  {/if}
191
+ <div class="flex items-center gap-x-4">
192
+ <label class="flex items-center gap-x-1.5 text-sm select-none">
193
+ <input type="checkbox" bind:checked={showToken} />
194
+ <p class="leading-none">With token</p>
195
+ </label>
196
+ <button
197
+ class="flex items-center gap-x-2 rounded-md border bg-white px-1.5 py-0.5 text-sm shadow-xs transition dark:border-gray-800 dark:bg-gray-800"
198
+ use:copy={selectedSnippet.content}
199
+ >
200
+ <IconCopyCode classNames="text-xs" /> Copy code
201
+ </button>
202
+ </div>
203
+ </div>
204
+ <pre
205
+ class="overflow-x-auto rounded-lg border border-gray-200/80 bg-white px-4 py-6 text-sm shadow-xs dark:border-gray-800 dark:bg-gray-800/50">{@html highlight(
206
+ selectedSnippet.content,
207
+ selectedSnippet.language ?? lang
208
+ )}</pre>
209
  </div>
src/lib/utils/object.ts CHANGED
@@ -2,3 +2,13 @@
2
  export function keys<T extends object>(o: T): (keyof T)[] {
3
  return Object.keys(o) as (keyof T)[];
4
  }
 
 
 
 
 
 
 
 
 
 
 
2
  export function keys<T extends object>(o: T): (keyof T)[] {
3
  return Object.keys(o) as (keyof T)[];
4
  }
5
+
6
+ // typed Object.entries
7
+ export function entries<T extends object>(o: T): [keyof T, T[keyof T]][] {
8
+ return Object.entries(o) as [keyof T, T[keyof T]][];
9
+ }
10
+
11
+ // typed Object.fromEntries
12
+ export function fromEntries<T extends object>(entries: [keyof T, T[keyof T]][]): T {
13
+ return Object.fromEntries(entries) as T;
14
+ }