tjs-lang 0.8.0 → 0.8.1

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 (53) hide show
  1. package/CLAUDE.md +6 -2
  2. package/CONTEXT.md +4 -0
  3. package/demo/docs.json +12 -690
  4. package/dist/eslint.config.d.ts +2 -0
  5. package/dist/index.js +137 -135
  6. package/dist/index.js.map +4 -4
  7. package/dist/src/lang/emitters/js-wasm.d.ts +5 -1
  8. package/dist/src/lang/emitters/js.d.ts +9 -0
  9. package/dist/src/lang/index.d.ts +1 -0
  10. package/dist/src/lang/module-loader.d.ts +125 -0
  11. package/dist/src/lang/parser-transforms.d.ts +79 -0
  12. package/dist/src/lang/parser-types.d.ts +33 -0
  13. package/dist/src/lang/wasm.d.ts +67 -1
  14. package/dist/tjs-batteries.js +2 -2
  15. package/dist/tjs-batteries.js.map +2 -2
  16. package/dist/tjs-eval.js +39 -37
  17. package/dist/tjs-eval.js.map +3 -3
  18. package/dist/tjs-from-ts.js +2 -2
  19. package/dist/tjs-from-ts.js.map +2 -2
  20. package/dist/tjs-lang.js +102 -102
  21. package/dist/tjs-lang.js.map +3 -3
  22. package/dist/tjs-vm.js +50 -48
  23. package/dist/tjs-vm.js.map +3 -3
  24. package/docs/README.md +2 -0
  25. package/docs/lm-studio-setup.md +143 -0
  26. package/docs/universal-endpoint.md +122 -0
  27. package/llms.txt +8 -2
  28. package/package.json +5 -4
  29. package/src/batteries/audit.ts +3 -3
  30. package/src/batteries/llm.ts +8 -3
  31. package/src/builder.ts +0 -3
  32. package/src/cli/commands/test.ts +1 -1
  33. package/src/lang/docs.test.ts +0 -1
  34. package/src/lang/emitters/from-ts.ts +1 -1
  35. package/src/lang/emitters/js.ts +0 -1
  36. package/src/lang/linter.ts +1 -1
  37. package/src/lang/module-loader.test.ts +9 -5
  38. package/src/lang/module-loader.ts +4 -5
  39. package/src/lang/parser-params.ts +1 -1
  40. package/src/lang/parser-transforms.ts +12 -18
  41. package/src/lang/perf.test.ts +10 -4
  42. package/src/lang/runtime.ts +0 -1
  43. package/src/lang/wasm.test.ts +14 -14
  44. package/src/linalg/linalg.test.ts +8 -2
  45. package/src/linalg/vector-search.bench.test.ts +31 -10
  46. package/src/types/Type.ts +6 -6
  47. package/src/use-cases/asymmetric-client-server.test.ts +0 -2
  48. package/src/use-cases/client-server.test.ts +1 -1
  49. package/src/use-cases/unbundled-imports.test.ts +0 -1
  50. package/src/vm/runtime.ts +3 -3
  51. package/src/vm/vm.ts +3 -1
  52. package/dist/examples/modules/dist/main.d.ts +0 -34
  53. package/dist/examples/modules/dist/math.d.ts +0 -120
@@ -1901,8 +1901,14 @@ describe('module consolidation (Phase 0.5)', () => {
1901
1901
 
1902
1902
  const result = compileBlocksToModule(blocks)
1903
1903
  expect(result.exports).toHaveLength(2)
1904
- expect(result.exports[0]).toMatchObject({ id: 'b0', exportName: 'compute_0' })
1905
- expect(result.exports[1]).toMatchObject({ id: 'b1', exportName: 'compute_1' })
1904
+ expect(result.exports[0]).toMatchObject({
1905
+ id: 'b0',
1906
+ exportName: 'compute_0',
1907
+ })
1908
+ expect(result.exports[1]).toMatchObject({
1909
+ id: 'b1',
1910
+ exportName: 'compute_1',
1911
+ })
1906
1912
 
1907
1913
  // Instantiate and confirm both exports work
1908
1914
  const instance = await instantiateWasm(result.bytes)
@@ -2117,10 +2123,8 @@ function dbl(arr: Float32Array, len: 0) {
2117
2123
  buf[1] = 2
2118
2124
  buf[2] = 3
2119
2125
  buf[3] = 4
2120
-
2121
2126
  ;(globalThis as any).__test_inc(buf, 4) // [2, 3, 4, 5]
2122
2127
  expect(Array.from(buf)).toEqual([2, 3, 4, 5])
2123
-
2124
2128
  ;(globalThis as any).__test_dbl(buf, 4) // [4, 6, 8, 10]
2125
2129
  expect(Array.from(buf)).toEqual([4, 6, 8, 10])
2126
2130
  } finally {
@@ -2384,9 +2388,7 @@ export wasm function mul(a: f64, b: f64): f64 { return a * b }
2384
2388
  // Both should produce the same numeric results.
2385
2389
  const { tjs } = await import('./index')
2386
2390
  const { createRuntime } = await import('./runtime')
2387
- const { ModuleLoader, inMemoryFileSystem } = await import(
2388
- './module-loader'
2389
- )
2391
+ const { ModuleLoader, inMemoryFileSystem } = await import('./module-loader')
2390
2392
 
2391
2393
  const librarySource = `
2392
2394
  export wasm function dot3(
@@ -2568,9 +2570,7 @@ function compute(x: 0.0): 0.0 {
2568
2570
  expect(result.code).toContain('globalThis.__tjs_wasm_fast(a)')
2569
2571
  // The remaining import keeps `slow` only
2570
2572
  expect(result.code).toMatch(/import\s*\{\s*slow\s*\}\s*from/)
2571
- expect(result.code).not.toMatch(
2572
- /import\s*\{\s*fast\s*,\s*slow\s*\}\s*from/
2573
- )
2573
+ expect(result.code).not.toMatch(/import\s*\{\s*fast\s*,\s*slow\s*\}\s*from/)
2574
2574
  })
2575
2575
 
2576
2576
  it('composes multiple wasm functions from one library', async () => {
@@ -3046,9 +3046,7 @@ wasm function isOdd(n: i32): f64 {
3046
3046
  // inner loop.
3047
3047
  const { tjs } = await import('./index')
3048
3048
  const { createRuntime } = await import('./runtime')
3049
- const { ModuleLoader, inMemoryFileSystem } = await import(
3050
- './module-loader'
3051
- )
3049
+ const { ModuleLoader, inMemoryFileSystem } = await import('./module-loader')
3052
3050
 
3053
3051
  const loader = new ModuleLoader({
3054
3052
  fs: inMemoryFileSystem({
@@ -3162,7 +3160,9 @@ wasm function caller(): f64 {
3162
3160
  `
3163
3161
  const result = tjs(source, { runTests: false })
3164
3162
  // caller fails because takesTwo gets one arg instead of two
3165
- const callerResult = result.wasmCompiled!.find((b) => b.id === '__tjs_wasm_caller')
3163
+ const callerResult = result.wasmCompiled!.find(
3164
+ (b) => b.id === '__tjs_wasm_caller'
3165
+ )
3166
3166
  expect(callerResult).toBeDefined()
3167
3167
  expect(callerResult!.success).toBe(false)
3168
3168
  expect(callerResult!.error).toMatch(/takesTwo expects 2 arguments, got 1/)
@@ -203,8 +203,14 @@ function cosine(a, b, n) {
203
203
  // Orthogonal vectors → cosine 0
204
204
  const ox = wasmBuffer(Float32Array, 4)
205
205
  const oy = wasmBuffer(Float32Array, 4)
206
- ox[0] = 1; ox[1] = 0; ox[2] = 0; ox[3] = 0
207
- oy[0] = 0; oy[1] = 1; oy[2] = 0; oy[3] = 0
206
+ ox[0] = 1
207
+ ox[1] = 0
208
+ ox[2] = 0
209
+ ox[3] = 0
210
+ oy[0] = 0
211
+ oy[1] = 1
212
+ oy[2] = 0
213
+ oy[3] = 0
208
214
  const ortho = (globalThis as any).__test_cosine(ox, oy, 4)
209
215
  expect(ortho).toBeCloseTo(0, 4)
210
216
  } finally {
@@ -30,10 +30,7 @@ import { describe, it, expect } from 'bun:test'
30
30
  import { readFileSync } from 'node:fs'
31
31
  import { join } from 'node:path'
32
32
 
33
- const LINALG_SOURCE = readFileSync(
34
- join(import.meta.dir, 'index.tjs'),
35
- 'utf8'
36
- )
33
+ const LINALG_SOURCE = readFileSync(join(import.meta.dir, 'index.tjs'), 'utf8')
37
34
 
38
35
  // The inline baseline — single wasm{} block computing dot, magA, magB
39
36
  // together. Mirrors what guides/examples/tjs/wasm-vector-search.md does.
@@ -161,7 +158,12 @@ async function loadVariant(
161
158
  fnName: string,
162
159
  varName: string
163
160
  ): Promise<{
164
- search: (corpus: Float32Array, query: Float32Array, count: number, dim: number) => number
161
+ search: (
162
+ corpus: Float32Array,
163
+ query: Float32Array,
164
+ count: number,
165
+ dim: number
166
+ ) => number
165
167
  wasmBuffer: (Ctor: any, len: number) => any
166
168
  }> {
167
169
  await new Function(
@@ -296,13 +298,28 @@ describe('Canonical demo: vector-search across three forms', () => {
296
298
  const warmCount = Math.min(100, cfg.count)
297
299
  for (let w = 0; w < 3; w++) {
298
300
  inline.search(inlineCorpus, inlineQuery, warmCount, cfg.dim)
299
- composedJs.search(composedJsCorpus, composedJsQuery, warmCount, cfg.dim)
300
- composedWasm.search(composedWasmCorpus, composedWasmQuery, warmCount, cfg.dim)
301
+ composedJs.search(
302
+ composedJsCorpus,
303
+ composedJsQuery,
304
+ warmCount,
305
+ cfg.dim
306
+ )
307
+ composedWasm.search(
308
+ composedWasmCorpus,
309
+ composedWasmQuery,
310
+ warmCount,
311
+ cfg.dim
312
+ )
301
313
  }
302
314
 
303
315
  // Time inline
304
316
  const inlineStart = performance.now()
305
- const inlineIdx = inline.search(inlineCorpus, inlineQuery, cfg.count, cfg.dim)
317
+ const inlineIdx = inline.search(
318
+ inlineCorpus,
319
+ inlineQuery,
320
+ cfg.count,
321
+ cfg.dim
322
+ )
306
323
  const inlineMs = performance.now() - inlineStart
307
324
 
308
325
  // Time composed JS-outer-loop
@@ -352,9 +369,13 @@ describe('Canonical demo: vector-search across three forms', () => {
352
369
  const jsRatio = t.composedJsMs / t.inlineMs
353
370
  const wasmRatio = t.composedWasmMs / t.inlineMs
354
371
  console.log(
355
- ` ${t.label.padEnd(12)} | ${t.inlineMs.toFixed(2).padStart(8)} | ${t.composedJsMs
372
+ ` ${t.label.padEnd(12)} | ${t.inlineMs
373
+ .toFixed(2)
374
+ .padStart(8)} | ${t.composedJsMs
375
+ .toFixed(2)
376
+ .padStart(11)} | ${jsRatio
356
377
  .toFixed(2)
357
- .padStart(11)} | ${jsRatio.toFixed(2).padStart(6)}x | ${t.composedWasmMs
378
+ .padStart(6)}x | ${t.composedWasmMs
358
379
  .toFixed(2)
359
380
  .padStart(13)} | ${wasmRatio.toFixed(2).padStart(5)}x`
360
381
  )
package/src/types/Type.ts CHANGED
@@ -686,7 +686,7 @@ export interface FunctionPredicateSpec {
686
686
  }
687
687
 
688
688
  /** A runtime type that validates function signatures */
689
- // eslint-disable-next-line @typescript-eslint/ban-types
689
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
690
690
  export interface FunctionPredicateType extends RuntimeType<Function> {
691
691
  /** Parameter specification */
692
692
  readonly params: Record<string, any>
@@ -755,7 +755,7 @@ function kindOfExample(example: unknown): string | null {
755
755
  */
756
756
  export function FunctionPredicate(
757
757
  name: string,
758
- // eslint-disable-next-line @typescript-eslint/ban-types
758
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
759
759
  specOrFn: FunctionPredicateSpec | Function | (string | [string, TypeParam])[],
760
760
  specBuilder?: (...typeArgs: any[]) => FunctionPredicateSpec
761
761
  ): FunctionPredicateType | GenericFunctionPredicateType {
@@ -794,18 +794,18 @@ export function FunctionPredicate(
794
794
  return factory
795
795
  }
796
796
 
797
- /* eslint-disable @typescript-eslint/ban-types */
797
+ /* eslint-disable @typescript-eslint/no-unsafe-function-type */
798
798
  return _createFunctionPredicate(
799
799
  name,
800
800
  specOrFn as FunctionPredicateSpec | Function
801
801
  )
802
- /* eslint-enable @typescript-eslint/ban-types */
802
+ /* eslint-enable @typescript-eslint/no-unsafe-function-type */
803
803
  }
804
804
 
805
805
  /** Internal: create a non-generic FunctionPredicateType */
806
806
  function _createFunctionPredicate(
807
807
  name: string,
808
- // eslint-disable-next-line @typescript-eslint/ban-types
808
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
809
809
  specOrFn: FunctionPredicateSpec | Function
810
810
  ): FunctionPredicateType {
811
811
  let params: Record<string, any> = {}
@@ -853,7 +853,7 @@ function _createFunctionPredicate(
853
853
  // Structural validation: check arity and __tjs metadata
854
854
  const expectedArity = Object.keys(params).length
855
855
  if (expectedArity > 0) {
856
- // eslint-disable-next-line @typescript-eslint/ban-types
856
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
857
857
  const fn = value as Function
858
858
  const meta = (fn as any).__tjs
859
859
  if (meta?.params) {
@@ -82,7 +82,6 @@ describe('Use Case: Asymmetric Client-Server', () => {
82
82
 
83
83
  // Note: In a real scenario, client imports definitions (types/schema) but not heavy deps.
84
84
  // Here we reuse the atom definitions from 'batteries.ts' for the builder schema.
85
- // eslint-disable-next-line @typescript-eslint/no-var-requires
86
85
  const { coreAtoms } = require('../runtime')
87
86
  const clientBuilder = Agent.custom({
88
87
  ...coreAtoms,
@@ -154,7 +153,6 @@ describe('Use Case: Asymmetric Client-Server', () => {
154
153
  llmPredictBattery,
155
154
  })
156
155
 
157
- // eslint-disable-next-line @typescript-eslint/no-var-requires
158
156
  const { coreAtoms } = require('../runtime')
159
157
  const logic = Agent.custom({ ...coreAtoms, storeVectorize })
160
158
  .step({ op: 'storeVectorize', text: 'fail' })
@@ -116,7 +116,7 @@ describe('Use Case: Client-Server', () => {
116
116
  let data
117
117
  try {
118
118
  data = JSON.parse(text)
119
- } catch (e) {
119
+ } catch {
120
120
  console.error('Failed to parse concurrent response:', text)
121
121
  return { status: 500, result: text }
122
122
  }
@@ -14,7 +14,6 @@
14
14
  import { describe, it, expect, beforeAll, afterAll } from 'bun:test'
15
15
  import { fromTS } from '../lang/emitters/from-ts'
16
16
  import { tjs } from '../lang'
17
- import { createRuntime } from '../lang/runtime'
18
17
  import { mkdirSync, writeFileSync, rmSync, existsSync } from 'fs'
19
18
  import { join } from 'path'
20
19
 
package/src/vm/runtime.ts CHANGED
@@ -2202,7 +2202,7 @@ export const fetch = defineAtom(
2202
2202
  }
2203
2203
  } catch (e: any) {
2204
2204
  if (e.message.includes('allowedFetchDomains')) throw e
2205
- throw new Error(`Invalid URL: ${url}`)
2205
+ throw new Error(`Invalid URL: ${url}`, { cause: e })
2206
2206
  }
2207
2207
  }
2208
2208
 
@@ -2476,7 +2476,7 @@ export const transpileCode = defineAtom(
2476
2476
  try {
2477
2477
  return ctx.capabilities.code.transpile(resolvedCode)
2478
2478
  } catch (e: any) {
2479
- throw new Error(`Code transpilation failed: ${e.message}`)
2479
+ throw new Error(`Code transpilation failed: ${e.message}`, { cause: e })
2480
2480
  }
2481
2481
  },
2482
2482
  { docs: 'Transpile AsyncJS code to AST', cost: 1 }
@@ -2538,7 +2538,7 @@ export const runCode = defineAtom(
2538
2538
  try {
2539
2539
  ast = ctx.capabilities.code.transpile(resolvedCode)
2540
2540
  } catch (e: any) {
2541
- throw new Error(`Code transpilation failed: ${e.message}`)
2541
+ throw new Error(`Code transpilation failed: ${e.message}`, { cause: e })
2542
2542
  }
2543
2543
 
2544
2544
  if (ast.op !== 'seq') {
package/src/vm/vm.ts CHANGED
@@ -94,7 +94,9 @@ export class AgentVM<M extends Record<string, Atom<any, any>>> {
94
94
  try {
95
95
  ast = transpile(astOrToken).ast as BaseNode
96
96
  } catch (e: any) {
97
- throw new Error(`AJS transpilation failed: ${e.message}`)
97
+ throw new Error(`AJS transpilation failed: ${e.message}`, {
98
+ cause: e,
99
+ })
98
100
  }
99
101
  }
100
102
  } else {
@@ -1,34 +0,0 @@
1
- export function calculate(x?: number, y?: number): any;
2
- export namespace calculate {
3
- namespace __tjs {
4
- namespace params {
5
- namespace x {
6
- export namespace type {
7
- let kind: string;
8
- }
9
- export let required: boolean;
10
- let _default: null;
11
- export { _default as default };
12
- }
13
- namespace y {
14
- export namespace type_1 {
15
- let kind_1: string;
16
- export { kind_1 as kind };
17
- }
18
- export { type_1 as type };
19
- let required_1: boolean;
20
- export { required_1 as required };
21
- let _default_1: null;
22
- export { _default_1 as default };
23
- }
24
- }
25
- namespace returns {
26
- export namespace type_2 {
27
- let kind_2: string;
28
- export { kind_2 as kind };
29
- }
30
- export { type_2 as type };
31
- }
32
- let source: string;
33
- }
34
- }
@@ -1,120 +0,0 @@
1
- export function add(a?: number, b?: number): any;
2
- export namespace add {
3
- namespace __tjs {
4
- namespace params {
5
- namespace a {
6
- export namespace type {
7
- let kind: string;
8
- }
9
- export let required: boolean;
10
- let _default: null;
11
- export { _default as default };
12
- }
13
- namespace b {
14
- export namespace type_1 {
15
- let kind_1: string;
16
- export { kind_1 as kind };
17
- }
18
- export { type_1 as type };
19
- let required_1: boolean;
20
- export { required_1 as required };
21
- let _default_1: null;
22
- export { _default_1 as default };
23
- }
24
- }
25
- namespace returns {
26
- export namespace type_2 {
27
- let kind_2: string;
28
- export { kind_2 as kind };
29
- }
30
- export { type_2 as type };
31
- }
32
- let source: string;
33
- }
34
- }
35
- export function subtract(a?: number, b?: number): any;
36
- export namespace subtract {
37
- export namespace __tjs_1 {
38
- export namespace params_1 {
39
- export namespace a_1 {
40
- export namespace type_3 {
41
- let kind_3: string;
42
- export { kind_3 as kind };
43
- }
44
- export { type_3 as type };
45
- let required_2: boolean;
46
- export { required_2 as required };
47
- let _default_2: null;
48
- export { _default_2 as default };
49
- }
50
- export { a_1 as a };
51
- export namespace b_1 {
52
- export namespace type_4 {
53
- let kind_4: string;
54
- export { kind_4 as kind };
55
- }
56
- export { type_4 as type };
57
- let required_3: boolean;
58
- export { required_3 as required };
59
- let _default_3: null;
60
- export { _default_3 as default };
61
- }
62
- export { b_1 as b };
63
- }
64
- export { params_1 as params };
65
- export namespace returns_1 {
66
- export namespace type_5 {
67
- let kind_5: string;
68
- export { kind_5 as kind };
69
- }
70
- export { type_5 as type };
71
- }
72
- export { returns_1 as returns };
73
- let source_1: string;
74
- export { source_1 as source };
75
- }
76
- export { __tjs_1 as __tjs };
77
- }
78
- export function multiply(a?: number, b?: number): any;
79
- export namespace multiply {
80
- export namespace __tjs_2 {
81
- export namespace params_2 {
82
- export namespace a_2 {
83
- export namespace type_6 {
84
- let kind_6: string;
85
- export { kind_6 as kind };
86
- }
87
- export { type_6 as type };
88
- let required_4: boolean;
89
- export { required_4 as required };
90
- let _default_4: null;
91
- export { _default_4 as default };
92
- }
93
- export { a_2 as a };
94
- export namespace b_2 {
95
- export namespace type_7 {
96
- let kind_7: string;
97
- export { kind_7 as kind };
98
- }
99
- export { type_7 as type };
100
- let required_5: boolean;
101
- export { required_5 as required };
102
- let _default_5: null;
103
- export { _default_5 as default };
104
- }
105
- export { b_2 as b };
106
- }
107
- export { params_2 as params };
108
- export namespace returns_2 {
109
- export namespace type_8 {
110
- let kind_8: string;
111
- export { kind_8 as kind };
112
- }
113
- export { type_8 as type };
114
- }
115
- export { returns_2 as returns };
116
- let source_2: string;
117
- export { source_2 as source };
118
- }
119
- export { __tjs_2 as __tjs };
120
- }