tjs-lang 0.6.44 → 0.7.3

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 (86) hide show
  1. package/CLAUDE.md +85 -422
  2. package/README.md +15 -82
  3. package/bin/benchmarks.ts +7 -7
  4. package/bin/dev.ts +2 -1
  5. package/demo/autocomplete.test.ts +1 -1
  6. package/demo/docs.json +744 -48
  7. package/demo/src/demo-nav.ts +5 -5
  8. package/demo/src/index.ts +28 -36
  9. package/demo/src/module-sw.ts +1 -1
  10. package/demo/src/playground-shared.ts +17 -17
  11. package/demo/src/playground.ts +13 -1
  12. package/demo/src/style.ts +4 -1
  13. package/demo/src/tjs-playground.ts +5 -5
  14. package/demo/src/user-store.ts +2 -1
  15. package/demo/static/favicon.svg +17 -24
  16. package/demo/static/tosi-platform.json +9304 -0
  17. package/dist/index.js +158 -156
  18. package/dist/index.js.map +14 -13
  19. package/dist/scripts/compat-effect.d.ts +16 -0
  20. package/dist/scripts/compat-kysely.d.ts +13 -0
  21. package/dist/scripts/compat-radash.d.ts +13 -0
  22. package/dist/scripts/compat-superstruct.d.ts +13 -0
  23. package/dist/scripts/compat-ts-pattern.d.ts +13 -0
  24. package/dist/scripts/compat-zod.d.ts +12 -0
  25. package/dist/src/lang/emitters/from-ts.d.ts +1 -1
  26. package/dist/src/lang/emitters/js-tests.d.ts +4 -0
  27. package/dist/src/lang/emitters/js.d.ts +2 -2
  28. package/dist/src/lang/index.d.ts +1 -0
  29. package/dist/src/lang/json-schema.d.ts +40 -0
  30. package/dist/src/lang/parser-transforms.d.ts +14 -0
  31. package/dist/src/lang/runtime.d.ts +39 -6
  32. package/dist/src/types/Type.d.ts +5 -0
  33. package/dist/tjs-full.js +158 -156
  34. package/dist/tjs-full.js.map +14 -13
  35. package/dist/tjs-vm.js +44 -43
  36. package/dist/tjs-vm.js.map +5 -5
  37. package/docs/README.md +21 -20
  38. package/docs/WASM-QUICKSTART.md +283 -0
  39. package/docs/diagrams/architecture-shift.svg +117 -0
  40. package/docs/diagrams/compile-runtime.svg +130 -0
  41. package/docs/diagrams/icon-riff-1.svg +55 -0
  42. package/docs/diagrams/icon-riff-2.svg +62 -0
  43. package/docs/diagrams/icon-riff-3.svg +61 -0
  44. package/docs/diagrams/platform-overview.svg +114 -0
  45. package/docs/diagrams/safe-eval.svg +147 -0
  46. package/docs/eval-v4/arch-comparison.svg +277 -0
  47. package/docs/eval-v4/bundler-tree.svg +250 -0
  48. package/docs/eval-v4/http-lifecycle.svg +148 -0
  49. package/docs/function-predicate-design.md +8 -8
  50. package/docs/native-engine-integration.md +2 -2
  51. package/editors/codemirror/autocomplete.test.ts +29 -29
  52. package/package.json +10 -4
  53. package/src/cli/commands/convert.test.ts +11 -8
  54. package/src/cli/tjs.ts +1 -1
  55. package/src/lang/codegen.test.ts +117 -112
  56. package/src/lang/docs.test.ts +22 -22
  57. package/src/lang/docs.ts +5 -8
  58. package/src/lang/emitters/dts.test.ts +13 -13
  59. package/src/lang/emitters/from-ts.ts +36 -9
  60. package/src/lang/emitters/js-tests.ts +143 -28
  61. package/src/lang/emitters/js.ts +49 -28
  62. package/src/lang/features.test.ts +259 -43
  63. package/src/lang/from-ts.test.ts +3 -3
  64. package/src/lang/function-predicate.test.ts +1 -1
  65. package/src/lang/index.ts +8 -47
  66. package/src/lang/json-schema.test.ts +261 -0
  67. package/src/lang/json-schema.ts +167 -0
  68. package/src/lang/parser-params.ts +28 -44
  69. package/src/lang/parser-transforms.ts +255 -0
  70. package/src/lang/parser.test.ts +32 -13
  71. package/src/lang/parser.ts +49 -11
  72. package/src/lang/perf.test.ts +11 -11
  73. package/src/lang/roundtrip.test.ts +3 -3
  74. package/src/lang/runtime.test.ts +167 -0
  75. package/src/lang/runtime.ts +234 -46
  76. package/src/lang/transpiler.test.ts +21 -21
  77. package/src/lang/typescript-syntax.test.ts +11 -9
  78. package/src/types/Type.ts +38 -1
  79. package/src/use-cases/bootstrap.test.ts +7 -7
  80. package/src/use-cases/client-server.test.ts +1 -1
  81. package/src/use-cases/malicious-actor.test.ts +1 -1
  82. package/src/use-cases/rag-processor.test.ts +1 -1
  83. package/src/use-cases/sophisticated-agents.test.ts +2 -2
  84. package/src/use-cases/transpiler-llm.test.ts +1 -1
  85. package/src/use-cases/unbundled-imports.test.ts +9 -9
  86. package/tjs-lang.svg +17 -25
package/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  # TJS Platform
4
4
 
5
- ![tjs-lang logo](/tjs-lang.svg)
5
+ <center>
6
+ <tosi-lottie style="width: 40vmin; height: 40vmin;" src="./tosi-platform.json"><img alt="tjs-lang logo" style="width: 40vmin; height: 40vmin" src="tjs-lang.svg"></tosi-lottie>
7
+ </center>
6
8
 
7
9
  [playground](https://tjs-platform.web.app) | [github](https://github.com/tonioloewald/tjs-lang#readme) | [npm](https://www.npmjs.com/package/tjs-lang) | [discord](https://discord.gg/ramJ9rgky5)
8
10
 
@@ -16,21 +18,7 @@
16
18
 
17
19
  **TJS is also a toolchain.** It transpiles itself into JavaScript. It transpiles TypeScript into itself and then into JS. It turns function definitions into runtime contracts, documentation, and simple tests. It uses types both as contracts and examples. It allows inline tests of private module internals that disappear at runtime. It compresses transpilation, linting, testing, and documentation generation into a single fast pass. As for bundling? It allows it but it targets an unbundled web.
18
20
 
19
- ```
20
- ┌─────────────────────────────────────────────────────────────────────────┐
21
- │ TJS Platform │
22
- ├─────────────────────┬─────────────────────┬─────────────────────────────┤
23
- │ Language │ Runtime │ Safe Execution │
24
- ├─────────────────────┼─────────────────────┼─────────────────────────────┤
25
- │ TypeScript │ __tjs metadata │ AJS Agent │
26
- │ ↓ │ ↓ │ ↓ │
27
- │ TJS │ Runtime Validation │ JSON AST │
28
- │ ↓ │ ↓ │ ↓ │
29
- │ JavaScript │ Auto Documentation │ Gas-Limited VM │
30
- │ │ │ ↓ │
31
- │ │ │ Injected Capabilities │
32
- └─────────────────────┴─────────────────────┴─────────────────────────────┘
33
- ```
21
+ ![TJS Platform Overview](docs/diagrams/platform-overview.svg)
34
22
 
35
23
  ## The Problem
36
24
 
@@ -59,16 +47,16 @@ Write typed JavaScript where the type _is_ an example. No split-brain validation
59
47
 
60
48
  ```typescript
61
49
  // TJS: The type is an example AND a test
62
- function greet(name: 'World') -> 'Hello, World!' {
50
+ function greet(name: 'World'): 'Hello, World!' {
63
51
  return `Hello, ${name}!`
64
52
  }
65
53
  // At transpile time: greet('World') is called and checked against 'Hello, World!'
66
54
 
67
55
  // Runtime: The type becomes a contract
68
- console.log(greet.__tjs.params) // { name: { type: 'string', example: 'World', required: true } }
56
+ console.log(greet.__tjs.params) // { name: { type: 'string', example: 'World', required: true } }
69
57
 
70
58
  // Safety: Errors are values, not crashes
71
- const result = greet(123) // MonadicError: Expected string for 'greet.name', got number
59
+ const result = greet(123) // MonadicError: Expected string for 'greet.name', got number
72
60
  ```
73
61
 
74
62
  **Why it matters:**
@@ -80,24 +68,7 @@ const result = greet(123) // MonadicError: Expected string for 'greet.nam
80
68
  - **Zero build step** — transpiles in the browser, no webpack/Vite/Babel
81
69
  - **The compiler _is_ the client** — TJS transpiles itself _and_ TypeScript entirely client-side
82
70
 
83
- ```
84
- ┌─────────────────────────────────────────────────────────────────┐
85
- │ COMPILE TIME │
86
- │ │
87
- │ function greet(name: 'World') ──→ Parse ──→ Extract type │
88
- │ name = string │
89
- └─────────────────────────────────────────────────────────────────┘
90
-
91
- ┌─────────────────────────────────────────────────────────────────┐
92
- │ RUNTIME │
93
- │ │
94
- │ greet.__tjs = { params: { name: { type: 'string' } } } │
95
- │ │
96
- │ greet(123) ──→ Type Check ──┬──→ Pass ──→ Execute │
97
- │ └──→ Fail ──→ MonadicError │
98
- │ (no throw) │
99
- └─────────────────────────────────────────────────────────────────┘
100
- ```
71
+ ![Compile Time and Runtime Flow](docs/diagrams/compile-runtime.svg)
101
72
 
102
73
  ## AJS — Code That Travels
103
74
 
@@ -133,27 +104,7 @@ const result = await vm.run(
133
104
 
134
105
  ## The Architecture Shift
135
106
 
136
- ```
137
- ❌ OLD WAY: Data-to-Code
138
- ┌────────┐ request ┌────────┐ fetch 100 rows ┌──────────┐
139
- │ Client │ ────────────→ │ Server │ ───────────────→ │ Database │
140
- │ │ ←──────────── │ │ ←─────────────── │ │
141
- └────────┘ 5 rows └────────┘ 100 rows └──────────┘
142
- (after filtering 95 away)
143
- ```
144
-
145
- _High latency. High bandwidth. Validate at every layer._
146
-
147
- ```
148
- ✅ TJS WAY: Code-to-Data
149
- ┌────────┐ send agent ┌────────┐ run at data ┌──────────┐
150
- │ Client │ ────────────→ │ Edge │ ───────────────→ │ Database │
151
- │ │ ←──────────── │ │ ←─────────────── │ │
152
- └────────┘ 5 rows └────────┘ 5 rows └──────────┘
153
- (agent filtered at source)
154
- ```
155
-
156
- _Low latency. Zero waste. Validate once._
107
+ ![Architecture Shift: Data-to-Code vs Code-to-Data](docs/diagrams/architecture-shift.svg)
157
108
 
158
109
  The agent carries its own validation. The server grants capabilities. Caching happens automatically because the query _is_ the code.
159
110
 
@@ -187,26 +138,7 @@ const { result, fuelUsed } = await Eval({
187
138
 
188
139
  The untrusted code thinks it has `fetch`, but it only has _your_ `fetch`. No CSP violations. No infinite loops. No access to anything you didn't explicitly grant.
189
140
 
190
- ```
191
- ┌─────────────────┐
192
- │ Untrusted Code │
193
- └────────┬────────┘
194
-
195
- ┌───────────┬───────┴───────┬───────────┐
196
- ↓ ↓ ↓ ↓
197
- fetch() fs.read() loop console
198
- │ │ │ │
199
- ↓ ↓ ↓ ↓
200
- ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
201
- │Granted? │ │Granted? │ │Fuel left│ │Granted? │
202
- └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
203
- Y │ N N │ Y │ N N │
204
- ↓ ↓ ↓ ↓ ↓ ↓
205
- ┌────────┐ ┌───────┐ Continue Halt Block
206
- │ Your │ │ Block │ │
207
- │safeFetch│ └───────┘ ↓
208
- └────────┘
209
- ```
141
+ ![Safe Eval: Capability-Based Security](docs/diagrams/safe-eval.svg)
210
142
 
211
143
  ## Quick Start
212
144
 
@@ -236,7 +168,7 @@ console.log(result) // { result: 42 }
236
168
  import { tjs } from 'tjs-lang'
237
169
 
238
170
  const { code, metadata } = tjs`
239
- function add(a: 0, b: 0) -> 0 {
171
+ function add(a: 0, b: 0): 0 {
240
172
  return a + b
241
173
  }
242
174
  `
@@ -281,9 +213,10 @@ The cost of "safe eval"—compare to a 200MB Docker image:
281
213
 
282
214
  ## Documentation
283
215
 
284
- - **[TJS Language Guide](DOCS-TJS.md)** — Types, syntax, runtime
285
- - **[AJS Runtime Guide](DOCS-AJS.md)** — VM, atoms, capabilities
286
- - **[Architecture Deep Dive](CONTEXT.md)** — How it all fits together
216
+ - **[TJS Language Guide](https://github.com/tonioloewald/tjs-lang/blob/main/DOCS-TJS.md)** — Types, syntax, runtime
217
+ - **[AJS Runtime Guide](https://github.com/tonioloewald/tjs-lang/blob/main/DOCS-AJS.md)** — VM, atoms, capabilities
218
+ - **[WASM Quick Start](https://github.com/tonioloewald/tjs-lang/blob/main/docs/WASM-QUICKSTART.md)** — Build WASM-accelerated libraries with zero toolchain setup
219
+ - **[Architecture Deep Dive](https://github.com/tonioloewald/tjs-lang/blob/main/CONTEXT.md)** — How it all fits together
287
220
  - **[Playground](https://tjs-platform.web.app)** — Try it now
288
221
 
289
222
  ## Installation
package/bin/benchmarks.ts CHANGED
@@ -47,7 +47,7 @@ console.log('Running TJS benchmarks...\n')
47
47
  // CLI Cold Start
48
48
  console.log('CLI Cold Start:')
49
49
  const testFile = '/tmp/bench-test.tjs'
50
- writeFileSync(testFile, `function add(a: 1, b: 2) -> 0 { return a + b }`)
50
+ writeFileSync(testFile, `function add(a: 1, b: 2) -> 3 { return a + b }`)
51
51
 
52
52
  function measureCLI(cmd: string): number {
53
53
  const times: number[] = []
@@ -197,9 +197,9 @@ results.push({
197
197
  console.log('\n3-Function Chain:')
198
198
 
199
199
  // Create safe chain
200
- const safeStep1Result = tjs(`function safeStep1(x: 0) -> 0 { return x * 2 }`)
201
- const safeStep2Result = tjs(`function safeStep2(x: 0) -> 0 { return x + 10 }`)
202
- const safeStep3Result = tjs(`function safeStep3(x: 0) -> 0 { return x / 2 }`)
200
+ const safeStep1Result = tjs(`function safeStep1(x: 5) -> 10 { return x * 2 }`)
201
+ const safeStep2Result = tjs(`function safeStep2(x: 10) -> 20 { return x + 10 }`)
202
+ const safeStep3Result = tjs(`function safeStep3(x: 20) -> 10 { return x / 2 }`)
203
203
 
204
204
  const safeStep1 = new Function(`${safeStep1Result.code}; return safeStep1;`)()
205
205
  const safeStep2 = new Function(`${safeStep2Result.code}; return safeStep2;`)()
@@ -207,13 +207,13 @@ const safeStep3 = new Function(`${safeStep3Result.code}; return safeStep3;`)()
207
207
 
208
208
  // Create unsafe chain with (!)
209
209
  const unsafeStep1Result = tjs(
210
- `function unsafeStep1(! x: 0) -> 0 { return x * 2 }`
210
+ `function unsafeStep1(! x: 5) -> 10 { return x * 2 }`
211
211
  )
212
212
  const unsafeStep2Result = tjs(
213
- `function unsafeStep2(! x: 0) -> 0 { return x + 10 }`
213
+ `function unsafeStep2(! x: 10) -> 20 { return x + 10 }`
214
214
  )
215
215
  const unsafeStep3Result = tjs(
216
- `function unsafeStep3(! x: 0) -> 0 { return x / 2 }`
216
+ `function unsafeStep3(! x: 20) -> 10 { return x / 2 }`
217
217
  )
218
218
 
219
219
  const unsafeStep1 = new Function(
package/bin/dev.ts CHANGED
@@ -78,8 +78,9 @@ async function buildDemo() {
78
78
  })
79
79
 
80
80
  // Copy static files (including TFS service worker — must not be bundled)
81
- await $`cp demo/index.html demo/static/favicon.svg demo/static/photo-*.jpg tjs-lang.svg demo/src/tfs-worker.js .demo/`
81
+ await $`cp demo/index.html demo/static/favicon.svg demo/static/photo-*.jpg demo/static/tosi-platform.json tjs-lang.svg demo/src/tfs-worker.js .demo/`
82
82
  await $`cp -r demo/static/texts .demo/`
83
+ await $`mkdir -p .demo/docs && cp -r docs/diagrams .demo/docs/ 2>/dev/null || true`
83
84
 
84
85
  console.log('Build complete!')
85
86
  } catch (error) {
@@ -54,7 +54,7 @@ describe('getCompletions', () => {
54
54
 
55
55
  it('should suggest types after return arrow', () => {
56
56
  const completions = getCompletions({
57
- source: 'function foo() -> ',
57
+ source: 'function foo(): ',
58
58
  position: 18,
59
59
  })
60
60