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.
- package/CLAUDE.md +85 -422
- package/README.md +15 -82
- package/bin/benchmarks.ts +7 -7
- package/bin/dev.ts +2 -1
- package/demo/autocomplete.test.ts +1 -1
- package/demo/docs.json +744 -48
- package/demo/src/demo-nav.ts +5 -5
- package/demo/src/index.ts +28 -36
- package/demo/src/module-sw.ts +1 -1
- package/demo/src/playground-shared.ts +17 -17
- package/demo/src/playground.ts +13 -1
- package/demo/src/style.ts +4 -1
- package/demo/src/tjs-playground.ts +5 -5
- package/demo/src/user-store.ts +2 -1
- package/demo/static/favicon.svg +17 -24
- package/demo/static/tosi-platform.json +9304 -0
- package/dist/index.js +158 -156
- package/dist/index.js.map +14 -13
- package/dist/scripts/compat-effect.d.ts +16 -0
- package/dist/scripts/compat-kysely.d.ts +13 -0
- package/dist/scripts/compat-radash.d.ts +13 -0
- package/dist/scripts/compat-superstruct.d.ts +13 -0
- package/dist/scripts/compat-ts-pattern.d.ts +13 -0
- package/dist/scripts/compat-zod.d.ts +12 -0
- package/dist/src/lang/emitters/from-ts.d.ts +1 -1
- package/dist/src/lang/emitters/js-tests.d.ts +4 -0
- package/dist/src/lang/emitters/js.d.ts +2 -2
- package/dist/src/lang/index.d.ts +1 -0
- package/dist/src/lang/json-schema.d.ts +40 -0
- package/dist/src/lang/parser-transforms.d.ts +14 -0
- package/dist/src/lang/runtime.d.ts +39 -6
- package/dist/src/types/Type.d.ts +5 -0
- package/dist/tjs-full.js +158 -156
- package/dist/tjs-full.js.map +14 -13
- package/dist/tjs-vm.js +44 -43
- package/dist/tjs-vm.js.map +5 -5
- package/docs/README.md +21 -20
- package/docs/WASM-QUICKSTART.md +283 -0
- package/docs/diagrams/architecture-shift.svg +117 -0
- package/docs/diagrams/compile-runtime.svg +130 -0
- package/docs/diagrams/icon-riff-1.svg +55 -0
- package/docs/diagrams/icon-riff-2.svg +62 -0
- package/docs/diagrams/icon-riff-3.svg +61 -0
- package/docs/diagrams/platform-overview.svg +114 -0
- package/docs/diagrams/safe-eval.svg +147 -0
- package/docs/eval-v4/arch-comparison.svg +277 -0
- package/docs/eval-v4/bundler-tree.svg +250 -0
- package/docs/eval-v4/http-lifecycle.svg +148 -0
- package/docs/function-predicate-design.md +8 -8
- package/docs/native-engine-integration.md +2 -2
- package/editors/codemirror/autocomplete.test.ts +29 -29
- package/package.json +10 -4
- package/src/cli/commands/convert.test.ts +11 -8
- package/src/cli/tjs.ts +1 -1
- package/src/lang/codegen.test.ts +117 -112
- package/src/lang/docs.test.ts +22 -22
- package/src/lang/docs.ts +5 -8
- package/src/lang/emitters/dts.test.ts +13 -13
- package/src/lang/emitters/from-ts.ts +36 -9
- package/src/lang/emitters/js-tests.ts +143 -28
- package/src/lang/emitters/js.ts +49 -28
- package/src/lang/features.test.ts +259 -43
- package/src/lang/from-ts.test.ts +3 -3
- package/src/lang/function-predicate.test.ts +1 -1
- package/src/lang/index.ts +8 -47
- package/src/lang/json-schema.test.ts +261 -0
- package/src/lang/json-schema.ts +167 -0
- package/src/lang/parser-params.ts +28 -44
- package/src/lang/parser-transforms.ts +255 -0
- package/src/lang/parser.test.ts +32 -13
- package/src/lang/parser.ts +49 -11
- package/src/lang/perf.test.ts +11 -11
- package/src/lang/roundtrip.test.ts +3 -3
- package/src/lang/runtime.test.ts +167 -0
- package/src/lang/runtime.ts +234 -46
- package/src/lang/transpiler.test.ts +21 -21
- package/src/lang/typescript-syntax.test.ts +11 -9
- package/src/types/Type.ts +38 -1
- package/src/use-cases/bootstrap.test.ts +7 -7
- package/src/use-cases/client-server.test.ts +1 -1
- package/src/use-cases/malicious-actor.test.ts +1 -1
- package/src/use-cases/rag-processor.test.ts +1 -1
- package/src/use-cases/sophisticated-agents.test.ts +2 -2
- package/src/use-cases/transpiler-llm.test.ts +1 -1
- package/src/use-cases/unbundled-imports.test.ts +9 -9
- package/tjs-lang.svg +17 -25
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# TJS Platform
|
|
4
4
|
|
|
5
|
-
|
|
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
|
+

|
|
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')
|
|
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)
|
|
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)
|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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)
|
|
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
|
-
- **[
|
|
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) ->
|
|
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:
|
|
201
|
-
const safeStep2Result = tjs(`function safeStep2(x:
|
|
202
|
-
const safeStep3Result = tjs(`function safeStep3(x:
|
|
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:
|
|
210
|
+
`function unsafeStep1(! x: 5) -> 10 { return x * 2 }`
|
|
211
211
|
)
|
|
212
212
|
const unsafeStep2Result = tjs(
|
|
213
|
-
`function unsafeStep2(! x:
|
|
213
|
+
`function unsafeStep2(! x: 10) -> 20 { return x + 10 }`
|
|
214
214
|
)
|
|
215
215
|
const unsafeStep3Result = tjs(
|
|
216
|
-
`function unsafeStep3(! x:
|
|
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) {
|