tjs-lang 0.2.7 → 0.3.0

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.
Files changed (40) hide show
  1. package/demo/docs.json +32 -26
  2. package/demo/src/examples.ts +23 -83
  3. package/demo/src/playground-shared.ts +666 -0
  4. package/demo/src/tjs-playground.ts +65 -550
  5. package/demo/src/ts-examples.ts +5 -4
  6. package/demo/src/ts-playground.ts +50 -414
  7. package/dist/index.js +143 -160
  8. package/dist/index.js.map +12 -12
  9. package/dist/src/lang/emitters/js.d.ts +34 -2
  10. package/dist/src/lang/index.d.ts +1 -1
  11. package/dist/src/lang/types.d.ts +1 -1
  12. package/dist/src/types/Type.d.ts +3 -1
  13. package/dist/tjs-full.js +143 -160
  14. package/dist/tjs-full.js.map +12 -12
  15. package/dist/tjs-transpiler.js +122 -55
  16. package/dist/tjs-transpiler.js.map +9 -8
  17. package/dist/tjs-vm.js +14 -14
  18. package/dist/tjs-vm.js.map +5 -5
  19. package/docs/docs.json +792 -0
  20. package/docs/index.js +2652 -2835
  21. package/docs/index.js.map +11 -10
  22. package/editors/codemirror/ajs-language.ts +27 -1
  23. package/editors/codemirror/autocomplete.test.ts +3 -3
  24. package/package.json +1 -1
  25. package/src/lang/codegen.test.ts +11 -11
  26. package/src/lang/emitters/from-ts.ts +1 -1
  27. package/src/lang/emitters/js.ts +228 -4
  28. package/src/lang/index.ts +0 -3
  29. package/src/lang/inference.ts +40 -8
  30. package/src/lang/lang.test.ts +192 -35
  31. package/src/lang/roundtrip.test.ts +155 -0
  32. package/src/lang/runtime.ts +7 -0
  33. package/src/lang/types.ts +2 -0
  34. package/src/lang/typescript-syntax.test.ts +6 -4
  35. package/src/lang/wasm.test.ts +20 -0
  36. package/src/lang/wasm.ts +143 -0
  37. package/src/types/Type.test.ts +64 -0
  38. package/src/types/Type.ts +22 -1
  39. package/src/use-cases/transpiler-integration.test.ts +10 -10
  40. package/src/vm/atoms/batteries.ts +2 -0
@@ -103,7 +103,7 @@ export const examples: Example[] = [
103
103
  description: 'Fetch weather data (no API key needed)',
104
104
  group: 'api',
105
105
  code: `function getWeather({ lat = 37.7749, lon = -122.4194 }) {
106
- let url = \`https://api.open-meteo.com/v1/forecast?latitude=\${lat}&longitude=\${lon}&current_weather=true\`
106
+ let url = 'https://api.open-meteo.com/v1/forecast?latitude=' + lat + '&longitude=' + lon + '&current_weather=true'
107
107
  let response = httpFetch({ url, cache: 1800 })
108
108
  let weather = response.current_weather
109
109
  return { weather }
@@ -114,7 +114,7 @@ export const examples: Example[] = [
114
114
  description: 'Search Apple iTunes catalog',
115
115
  group: 'api',
116
116
  code: `function searchMusic({ query = 'Beatles', limit = 5 }) {
117
- let url = \`https://itunes.apple.com/search?term=\${query}&limit=\${limit}&media=music\`
117
+ let url = 'https://itunes.apple.com/search?term=' + query + '&limit=' + limit + '&media=music'
118
118
  let response = httpFetch({ url, cache: 3600 })
119
119
  let tracks = response.results.map(x => ({
120
120
  artist: x.artistName,
@@ -129,7 +129,7 @@ export const examples: Example[] = [
129
129
  description: 'Search GitHub repositories',
130
130
  group: 'api',
131
131
  code: `function searchRepos({ query = 'tosijs', perPage = 5 }) {
132
- let url = \`https://api.github.com/search/repositories?q=\${query}&per_page=\${perPage}&sort=stars\`
132
+ let url = 'https://api.github.com/search/repositories?q=' + query + '&per_page=' + perPage + '&sort=stars'
133
133
  let response = httpFetch({ url, cache: 300 })
134
134
  let repos = response.items.map(x => ({
135
135
  name: x.full_name,
@@ -158,10 +158,10 @@ export const examples: Example[] = [
158
158
  code: `function summarize({ source = 'coffee-origins' }) {
159
159
  // Fetch text from our sample documents
160
160
  // Options: 'coffee-origins', 'ai-history', 'renewable-energy'
161
- let url = \`/texts/\${source}.txt\`
161
+ let url = '/texts/' + source + '.txt'
162
162
  let text = httpFetch({ url })
163
163
 
164
- let prompt = \`Summarize the following text in 2-3 sentences:\n\n\${text}\`
164
+ let prompt = 'Summarize the following text in 2-3 sentences:\\n\\n' + text
165
165
  let summary = llmPredict({ prompt })
166
166
  return { source, summary }
167
167
  }`,
@@ -181,7 +181,7 @@ export const examples: Example[] = [
181
181
  hobbies: ['']
182
182
  })
183
183
 
184
- let prompt = \`Extract person info from this text: \${text}\`
184
+ let prompt = 'Extract person info from this text: ' + text
185
185
  let response = llmPredict({ prompt, options: { responseFormat: schema } })
186
186
  let person = JSON.parse(response)
187
187
  return { person }
@@ -195,12 +195,12 @@ export const examples: Example[] = [
195
195
  code: `function findCovers({ song = 'Yesterday', artist = 'Beatles' }) {
196
196
  // Search iTunes for the song
197
197
  let query = song + ' ' + artist
198
- let url = \`https://itunes.apple.com/search?term=\${query}&limit=25&media=music\`
198
+ let url = 'https://itunes.apple.com/search?term=' + query + '&limit=25&media=music'
199
199
  let response = httpFetch({ url, cache: 3600 })
200
200
 
201
201
  // Format results for LLM analysis
202
202
  let results = response.results || []
203
- let tracks = results.map(x => \`"\${x.trackName}" by \${x.artistName} (\${x.collectionName})\`)
203
+ let tracks = results.map(x => '"' + x.trackName + '" by ' + x.artistName + ' (' + x.collectionName + ')')
204
204
  let trackList = tracks.join('\\n')
205
205
 
206
206
  // Schema.response from example - much cleaner!
@@ -208,11 +208,7 @@ export const examples: Example[] = [
208
208
  covers: [{ track: '', artist: '', album: '' }]
209
209
  })
210
210
 
211
- let prompt = \`Search results for "\${song}" by \${artist}:
212
-
213
- \${trackList}
214
-
215
- List cover versions (tracks NOT by \${artist}).\`
211
+ let prompt = 'Search results for "' + song + '" by ' + artist + ':\\n\\n' + trackList + '\\n\\nList cover versions (tracks NOT by ' + artist + ').'
216
212
 
217
213
  let llmResponse = llmPredict({ prompt, options: { responseFormat: schema } })
218
214
  let parsed = JSON.parse(llmResponse)
@@ -226,19 +222,15 @@ List cover versions (tracks NOT by \${artist}).\`
226
222
  requiresApi: true,
227
223
  code: `function mathAssistant({ question = 'What is 23 * 47 + 156?' }) {
228
224
  // First, ask LLM to extract the calculation
229
- let extractPrompt = \`Extract the math expression from this question. Return ONLY the expression, nothing else.
230
- Question: \${question}\`
225
+ let extractPrompt = 'Extract the math expression from this question. Return ONLY the expression, nothing else.\\nQuestion: ' + question
231
226
  let expression = llmPredict({ prompt: extractPrompt })
232
227
 
233
228
  // Evaluate the expression (simple eval simulation)
234
- let calcPrompt = \`Calculate: \${expression}
235
- Return ONLY the numeric result.\`
229
+ let calcPrompt = 'Calculate: ' + expression + '\\nReturn ONLY the numeric result.'
236
230
  let calcResult = llmPredict({ prompt: calcPrompt })
237
231
 
238
232
  // Format the answer
239
- let answerPrompt = \`The user asked: "\${question}"
240
- The calculated result is: \${calcResult}
241
- Write a brief, friendly response with the answer.\`
233
+ let answerPrompt = 'The user asked: "' + question + '"\\nThe calculated result is: ' + calcResult + '\\nWrite a brief, friendly response with the answer.'
242
234
  let answer = llmPredict({ prompt: answerPrompt })
243
235
 
244
236
  return { question, expression: expression.trim(), result: calcResult.trim(), answer }
@@ -251,26 +243,15 @@ Write a brief, friendly response with the answer.\`
251
243
  requiresApi: true,
252
244
  code: `function collaborativeWriting({ topic = 'the future of renewable energy' }) {
253
245
  // Agent 1: Research Agent - generates key points
254
- let researchPrompt = \`You are a research agent. Generate 3 key facts or points about: \${topic}
255
- Format as a numbered list. Be concise.\`
246
+ let researchPrompt = 'You are a research agent. Generate 3 key facts or points about: ' + topic + '\\nFormat as a numbered list. Be concise.'
256
247
  let research = llmPredict({ prompt: researchPrompt })
257
248
 
258
249
  // Agent 2: Writer Agent - creates content from research
259
- let writerPrompt = \`You are a writer agent. Using these research points:
260
-
261
- \${research}
262
-
263
- Write a short, engaging paragraph (2-3 sentences) about \${topic}.
264
- Make it informative and accessible.\`
250
+ let writerPrompt = 'You are a writer agent. Using these research points:\\n\\n' + research + '\\n\\nWrite a short, engaging paragraph (2-3 sentences) about ' + topic + '.\\nMake it informative and accessible.'
265
251
  let article = llmPredict({ prompt: writerPrompt })
266
252
 
267
253
  // Agent 3: Editor Agent - reviews and improves
268
- let editorPrompt = \`You are an editor agent. Review this draft:
269
-
270
- "\${article}"
271
-
272
- Suggest one specific improvement. Then provide the improved version.
273
- Format: "Suggestion: [your suggestion]\\n\\nImproved: [improved text]"\`
254
+ let editorPrompt = 'You are an editor agent. Review this draft:\\n\\n"' + article + '"\\n\\nSuggest one specific improvement. Then provide the improved version.\\nFormat: "Suggestion: [your suggestion]\\n\\nImproved: [improved text]"'
274
255
  let edited = llmPredict({ prompt: editorPrompt })
275
256
 
276
257
  return {
@@ -357,36 +338,16 @@ Format: "Suggestion: [your suggestion]\\n\\nImproved: [improved text]"\`
357
338
  requiresApi: true,
358
339
  code: `function solveWithCode({ problem = 'Calculate the 10th Fibonacci number' }) {
359
340
  // System prompt with AsyncJS rules and example
360
- let systemContext = \`You write AsyncJS code. AsyncJS is a JavaScript subset.
361
-
362
- RULES:
363
- - NO: async, await, new, class, this, var, for loops
364
- - Use let for variables, while for loops
365
- - Return an object: return { result }
366
-
367
- EXAMPLE (factorial):
368
- function solve() {
369
- let result = 1
370
- let i = 5
371
- while (i > 1) {
372
- result = result * i
373
- i = i - 1
374
- }
375
- return { result }
376
- }
377
-
378
- Return ONLY the function code, nothing else.\`
341
+ let systemContext = 'You write AsyncJS code. AsyncJS is a JavaScript subset.\\n\\nRULES:\\n- NO: async, await, new, class, this, var, for loops\\n- Use let for variables, while for loops\\n- Return an object: return { result }\\n\\nEXAMPLE (factorial):\\nfunction solve() {\\n let result = 1\\n let i = 5\\n while (i > 1) {\\n result = result * i\\n i = i - 1\\n }\\n return { result }\\n}\\n\\nReturn ONLY the function code, nothing else.'
379
342
 
380
- let prompt = \`\${systemContext}
381
-
382
- Write a function called "solve" that: \${problem}\`
343
+ let prompt = systemContext + '\\n\\nWrite a function called "solve" that: ' + problem
383
344
 
384
345
  let response = llmPredict({ prompt })
385
346
 
386
347
  // Clean up code - remove markdown fences, fix escapes, extract function
387
348
  let code = response
388
- code = code.replace(/\`\`\`(?:javascript|js|asyncjs)?\\n?/g, '')
389
- code = code.replace(/\\n?\`\`\`/g, '')
349
+ code = code.replace(/\\\`\\\`\\\`(?:javascript|js|asyncjs)?\\n?/g, '')
350
+ code = code.replace(/\\n?\\\`\\\`\\\`/g, '')
390
351
  code = code.replace(/\\\\n/g, '\\n')
391
352
  code = code.replace(/\\\\t/g, '\\t')
392
353
  code = code.replace(/\\\\"/g, '"')
@@ -425,43 +386,22 @@ Write a function called "solve" that: \${problem}\`
425
386
  requiresApi: true,
426
387
  code: `function generateCode({ task = 'Calculate the factorial of n' }) {
427
388
  // System prompt with AsyncJS rules and complete example
428
- let systemContext = \`You write AsyncJS code. AsyncJS is a subset of JavaScript.
429
-
430
- RULES:
431
- - Types by example: fn(n: 5) means required number param with example value 5
432
- - NO: async, await, new, class, this, var, for, generator functions (function*)
433
- - Use let for variables, while for loops
434
- - Return an object: return { result }
435
-
436
- EXAMPLE - calculating sum of 1 to n:
437
- function sumTo(n: 10) {
438
- let sum = 0
439
- let i = 1
440
- while (i <= n) {
441
- sum = sum + i
442
- i = i + 1
443
- }
444
- return { result: sum }
445
- }\`
389
+ let systemContext = 'You write AsyncJS code. AsyncJS is a subset of JavaScript.\\n\\nRULES:\\n- Types by example: fn(n: 5) means required number param with example value 5\\n- NO: async, await, new, class, this, var, for, generator functions (function*)\\n- Use let for variables, while for loops\\n- Return an object: return { result }\\n\\nEXAMPLE - calculating sum of 1 to n:\\nfunction sumTo(n: 10) {\\n let sum = 0\\n let i = 1\\n while (i <= n) {\\n sum = sum + i\\n i = i + 1\\n }\\n return { result: sum }\\n}'
446
390
 
447
391
  let schema = Schema.response('generated_code', {
448
392
  code: '',
449
393
  description: ''
450
394
  })
451
395
 
452
- let prompt = \`\${systemContext}
453
-
454
- Write an AsyncJS function for: \${task}
455
-
456
- Return ONLY valid AsyncJS code in the code field. Must start with "function" and use while loops (not for loops).\`
396
+ let prompt = systemContext + '\\n\\nWrite an AsyncJS function for: ' + task + '\\n\\nReturn ONLY valid AsyncJS code in the code field. Must start with "function" and use while loops (not for loops).'
457
397
 
458
398
  let response = llmPredict({ prompt, options: { responseFormat: schema } })
459
399
  let result = JSON.parse(response)
460
400
 
461
401
  // Clean up any markdown fences and fix escaped newlines
462
402
  let code = result.code
463
- code = code.replace(/\`\`\`(?:javascript|js)?\\n?/g, '')
464
- code = code.replace(/\\n?\`\`\`/g, '')
403
+ code = code.replace(/\\\`\\\`\\\`(?:javascript|js)?\\n?/g, '')
404
+ code = code.replace(/\\n?\\\`\\\`\\\`/g, '')
465
405
  code = code.replace(/\\\\n/g, '\\n')
466
406
  code = code.replace(/\\\\t/g, '\\t')
467
407
  code = code.trim()