tjs-lang 0.8.2 → 0.8.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 +4 -1
- package/demo/autocomplete.test.ts +37 -0
- package/demo/docs.json +698 -8
- package/demo/src/autocomplete.ts +40 -2
- package/demo/src/introspection-bridge.ts +140 -0
- package/demo/src/introspection-doc.test.ts +63 -0
- package/demo/src/playground-shared.ts +53 -0
- package/demo/src/tjs-playground.ts +21 -0
- package/editors/codemirror/ajs-language.ts +130 -44
- package/editors/codemirror/completion-source.test.ts +114 -0
- package/editors/introspect-value.test.ts +61 -0
- package/editors/introspect-value.ts +86 -0
- package/editors/scope-symbols.test.ts +113 -0
- package/editors/scope-symbols.ts +173 -0
- package/package.json +2 -1
- package/src/lang/index.ts +22 -0
- package/src/lang/predicate-schema.test.ts +97 -0
- package/src/lang/predicate-schema.ts +168 -0
- package/src/lang/predicate.test.ts +184 -0
- package/src/lang/predicate.ts +550 -0
- package/src/lang/suggest.test.ts +84 -0
- package/src/lang/transpiler.ts +26 -0
- package/src/vm/atom-effects.test.ts +72 -0
- package/src/vm/atoms/batteries.ts +12 -0
- package/src/vm/runtime.ts +51 -0
package/CLAUDE.md
CHANGED
|
@@ -86,6 +86,8 @@ bun run functions:serve # Local functions emulator
|
|
|
86
86
|
- `src/lang/inference.ts` - Type inference from example values
|
|
87
87
|
- `src/lang/json-schema.ts` - JSON Schema generation from TypeDescriptors and example values
|
|
88
88
|
- `src/lang/linter.ts` - Static analysis (unused vars, unreachable code, no-explicit-new)
|
|
89
|
+
- `src/lang/predicate.ts` - Predicate-safety verifier: certifies a cluster of pure, synchronous, composable predicates (reads the atom `effects` tag via `effectfulFromAtoms`); verified predicates compile to native JS. Also `suggest()` — mines a cluster for autocomplete completions (keyword sets → `value`s, `startsWith` guards → open-ended `stub`s like `var(--`; mined values run through the compiled predicate so they're guaranteed valid). Exported from `tjs-lang/lang`. See `experiments/predicates/` (CSS torture set + perf + suggest demo)
|
|
90
|
+
- `src/lang/predicate-schema.ts` - Predicate-aware JSON-Schema: the `$predicate` keyword (computational types). `compilePredicateSchema`/`validatePredicateSchema` — structure for naive validators, `$predicate` for aware ones (progressive enhancement). The serializable-into-JSON-Schema endgame; exported from `tjs-lang/lang`
|
|
89
91
|
- `src/lang/runtime.ts` - TJS runtime (monadic errors, type checking, wrapClass)
|
|
90
92
|
- `src/lang/wasm.ts` - WASM compiler (opcodes, disassembler, bytecode generation; multi-function module composition; wasm-to-wasm `call <index>` resolution)
|
|
91
93
|
- `src/lang/emitters/js-wasm.ts` - JS bootstrap emitter for compiled wasm modules (one `WebAssembly.compile` per file, name→export-index table, type-aware wrappers)
|
|
@@ -264,7 +266,7 @@ Coverage targets: 98% lines on `src/vm/runtime.ts` (security-critical), 80%+ ove
|
|
|
264
266
|
|
|
265
267
|
### Adding a New Atom
|
|
266
268
|
|
|
267
|
-
1. Define with `defineAtom(opCode, inputSchema, outputSchema, implementation, { cost, timeoutMs, docs })`
|
|
269
|
+
1. Define with `defineAtom(opCode, inputSchema, outputSchema, implementation, { cost, timeoutMs, docs, effects })`
|
|
268
270
|
2. Add to `src/vm/atoms/` and export from `src/vm/atoms/index.ts`
|
|
269
271
|
3. Add tests
|
|
270
272
|
4. Run `bun run test:fast`
|
|
@@ -274,6 +276,7 @@ Coverage targets: 98% lines on `src/vm/runtime.ts` (security-critical), 80%+ ove
|
|
|
274
276
|
- `cost` can be static number or dynamic: `(input, ctx) => number`
|
|
275
277
|
- `timeoutMs` defaults to 1000ms; use `0` for no timeout (e.g., `seq`)
|
|
276
278
|
- Atoms are always async; fuel deduction is automatic in the `exec` wrapper
|
|
279
|
+
- `effects` defaults to `'pure'`; **set `'io'` for any atom that touches `ctx.capabilities` (fetch/store/llm/agent/code), is nondeterministic (random/uuid), or has side effects (console)**. This drives predicate-safety (a predicate may only call pure atoms — see `experiments/predicates/`). Core IO atoms are tagged centrally via `EFFECTFUL_CORE_OPS` in `runtime.ts`; the invariant is guarded by `src/vm/atom-effects.test.ts`.
|
|
277
280
|
|
|
278
281
|
### Debugging Agents
|
|
279
282
|
|
|
@@ -40,6 +40,43 @@ describe('getCompletions', () => {
|
|
|
40
40
|
})
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
+
describe('destructured bindings (scope-aware)', () => {
|
|
44
|
+
// Regression: the old regex `const NAME =` extractor missed all
|
|
45
|
+
// destructuring, so the tosijs todo example suggested nothing.
|
|
46
|
+
const todo = `import { elements, tosi } from 'tosijs'
|
|
47
|
+
const { todoApp } = tosi({ todoApp: { items: [], newItem: '' } })
|
|
48
|
+
const { h1, ul, template, li, label, input, button } = elements
|
|
49
|
+
`
|
|
50
|
+
|
|
51
|
+
it('suggests destructured locals (todoApp, h1, button)', () => {
|
|
52
|
+
const completions = getCompletions({
|
|
53
|
+
source: todo,
|
|
54
|
+
position: todo.length,
|
|
55
|
+
})
|
|
56
|
+
const labels = completions.map((c) => c.label)
|
|
57
|
+
expect(labels).toContain('todoApp')
|
|
58
|
+
expect(labels).toContain('h1')
|
|
59
|
+
expect(labels).toContain('button')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('shows where a destructured binding came from', () => {
|
|
63
|
+
const completions = getCompletions({
|
|
64
|
+
source: todo,
|
|
65
|
+
position: todo.length,
|
|
66
|
+
})
|
|
67
|
+
expect(completions.find((c) => c.label === 'h1')?.detail).toBe(
|
|
68
|
+
'∈ elements'
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('filters destructured locals by prefix', () => {
|
|
73
|
+
const src = todo + 'tod'
|
|
74
|
+
const completions = getCompletions({ source: src, position: src.length })
|
|
75
|
+
expect(completions.map((c) => c.label)).toContain('todoApp')
|
|
76
|
+
expect(completions.every((c) => c.label.startsWith('tod'))).toBe(true)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
43
80
|
describe('type completions', () => {
|
|
44
81
|
it('should suggest types after colon', () => {
|
|
45
82
|
const completions = getCompletions({
|