tjs-lang 0.8.1 → 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.
Files changed (78) hide show
  1. package/CLAUDE.md +13 -4
  2. package/demo/autocomplete.test.ts +37 -0
  3. package/demo/docs.json +698 -8
  4. package/demo/examples.test.ts +6 -2
  5. package/demo/src/autocomplete.ts +40 -2
  6. package/demo/src/introspection-bridge.ts +140 -0
  7. package/demo/src/introspection-doc.test.ts +63 -0
  8. package/demo/src/playground-shared.ts +101 -16
  9. package/demo/src/playground-test-results.test.ts +112 -0
  10. package/demo/src/tjs-playground.ts +32 -5
  11. package/dist/examples/modules/dist/main.d.ts +34 -0
  12. package/dist/examples/modules/dist/math.d.ts +120 -0
  13. package/dist/index.js +115 -112
  14. package/dist/index.js.map +4 -4
  15. package/dist/src/lang/core.d.ts +1 -1
  16. package/dist/src/lang/dialect.d.ts +35 -0
  17. package/dist/src/lang/emitters/ast.d.ts +1 -1
  18. package/dist/src/lang/emitters/js-tests.d.ts +7 -0
  19. package/dist/src/lang/emitters/js.d.ts +12 -0
  20. package/dist/src/lang/index.d.ts +2 -1
  21. package/dist/src/lang/parser-types.d.ts +17 -0
  22. package/dist/src/lang/parser.d.ts +18 -0
  23. package/dist/src/lang/transpiler.d.ts +1 -0
  24. package/dist/src/lang/types.d.ts +18 -0
  25. package/dist/src/vm/runtime.d.ts +18 -0
  26. package/dist/src/vm/vm.d.ts +15 -1
  27. package/dist/tjs-batteries.js +2 -2
  28. package/dist/tjs-batteries.js.map +2 -2
  29. package/dist/tjs-eval.js +43 -43
  30. package/dist/tjs-eval.js.map +3 -3
  31. package/dist/tjs-from-ts.js +1 -1
  32. package/dist/tjs-from-ts.js.map +2 -2
  33. package/dist/tjs-lang.js +76 -73
  34. package/dist/tjs-lang.js.map +4 -4
  35. package/dist/tjs-vm.js +49 -49
  36. package/dist/tjs-vm.js.map +3 -3
  37. package/editors/codemirror/ajs-language.ts +130 -44
  38. package/editors/codemirror/completion-source.test.ts +114 -0
  39. package/editors/introspect-value.test.ts +61 -0
  40. package/editors/introspect-value.ts +86 -0
  41. package/editors/scope-symbols.test.ts +113 -0
  42. package/editors/scope-symbols.ts +173 -0
  43. package/llms.txt +1 -0
  44. package/package.json +21 -1
  45. package/src/batteries/audit.ts +3 -2
  46. package/src/cli/commands/check.ts +3 -2
  47. package/src/cli/commands/emit.ts +4 -2
  48. package/src/cli/commands/run.ts +6 -2
  49. package/src/cli/commands/types.ts +2 -2
  50. package/src/lang/codegen.test.ts +4 -1
  51. package/src/lang/core.ts +6 -4
  52. package/src/lang/dialect.test.ts +63 -0
  53. package/src/lang/dialect.ts +50 -0
  54. package/src/lang/emitters/ast.ts +145 -2
  55. package/src/lang/emitters/js-tests.ts +46 -37
  56. package/src/lang/emitters/js.ts +19 -2
  57. package/src/lang/features.test.ts +6 -5
  58. package/src/lang/index.ts +40 -5
  59. package/src/lang/parser-types.ts +17 -0
  60. package/src/lang/parser.test.ts +12 -6
  61. package/src/lang/parser.ts +113 -3
  62. package/src/lang/predicate-schema.test.ts +97 -0
  63. package/src/lang/predicate-schema.ts +168 -0
  64. package/src/lang/predicate.test.ts +184 -0
  65. package/src/lang/predicate.ts +550 -0
  66. package/src/lang/subset-invariant.test.ts +90 -0
  67. package/src/lang/suggest.test.ts +84 -0
  68. package/src/lang/transpiler.ts +34 -0
  69. package/src/lang/types.ts +18 -0
  70. package/src/lang/wasm.test.ts +8 -2
  71. package/src/linalg/linalg.test.ts +8 -2
  72. package/src/use-cases/batteries.test.ts +4 -0
  73. package/src/use-cases/local-helpers.test.ts +219 -0
  74. package/src/use-cases/timeout-overrides.test.ts +169 -0
  75. package/src/vm/atom-effects.test.ts +72 -0
  76. package/src/vm/atoms/batteries.ts +29 -3
  77. package/src/vm/runtime.ts +140 -4
  78. package/src/vm/vm.ts +47 -9
@@ -43,6 +43,7 @@ import {
43
43
  buildAutocompleteContext,
44
44
  type AutocompleteContext,
45
45
  } from './autocomplete-context'
46
+ import { IntrospectionBridge } from './introspection-bridge'
46
47
 
47
48
  // Available modules for autocomplete introspection
48
49
  const AVAILABLE_MODULES: Record<string, any> = {
@@ -149,7 +150,7 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
149
150
  // Split mode
150
151
  private _splitMode: null | 'code' | 'output' = null
151
152
  private _splitChannel: BroadcastChannel | null = null
152
- private _splitSessionId: string = ''
153
+ private _splitSessionId = ''
153
154
 
154
155
  // Build flags state
155
156
  private buildFlags = {
@@ -166,6 +167,8 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
166
167
  private autocompleteContext: AutocompleteContext | null = null
167
168
  private contextUpdateTimer: ReturnType<typeof setTimeout> | null = null
168
169
  private contextBuildPromise: Promise<void> | null = null
170
+ // Hidden sandbox for runtime-truth member completion (todoApp.items, …)
171
+ private introspectionBridge: IntrospectionBridge | null = null
169
172
 
170
173
  /**
171
174
  * Get metadata for autocomplete - returns all discovered functions
@@ -185,6 +188,15 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
185
188
  return this.autocompleteContext?.bindings
186
189
  }
187
190
 
191
+ /**
192
+ * Member completion from the introspection bridge — the user's REAL executed
193
+ * scope (`todoApp.items` → the live array). Returns undefined if the sandbox
194
+ * isn't ready, so the provider falls back to static completions.
195
+ */
196
+ private getMembers = (path: string) => {
197
+ return this.introspectionBridge?.members(path) ?? Promise.resolve(undefined)
198
+ }
199
+
188
200
  /**
189
201
  * Update autocomplete context (debounced)
190
202
  * Called when editor content changes.
@@ -198,6 +210,14 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
198
210
  const doBuild = async () => {
199
211
  const source = this.parts.tjsEditor.value
200
212
 
213
+ // Refresh the introspection sandbox (runtime-truth member completion).
214
+ // Independent of import-binding resolution below; failures are swallowed
215
+ // inside the bridge (keeps the last good sandbox).
216
+ if (!this.introspectionBridge) {
217
+ this.introspectionBridge = new IntrospectionBridge()
218
+ }
219
+ void this.introspectionBridge.refresh(source)
220
+
201
221
  try {
202
222
  const newContext = await buildAutocompleteContext(source)
203
223
  // Only update if we got bindings (keep last good context otherwise)
@@ -649,6 +669,7 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
649
669
  this.parts.tjsEditor.autocomplete = {
650
670
  getMetadata: this.getMetadataForAutocomplete,
651
671
  getLiveBindings: this.getLiveBindings,
672
+ getMembers: this.getMembers,
652
673
  }
653
674
 
654
675
  // Build initial autocomplete context immediately
@@ -860,21 +881,27 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
860
881
 
861
882
  private updateTestResults(result: any) {
862
883
  const tests = result.testResults
863
- const { passed, failed } = renderTestResults(
884
+ const { passed, failed, inconclusive } = renderTestResults(
864
885
  tests,
865
886
  this.parts.testsOutput,
866
887
  this.parts.tjsEditor,
867
888
  (line) => this.goToSourceLine(line)
868
889
  )
869
- this.updateTestsTabLabel(passed, failed)
890
+ this.updateTestsTabLabel(passed, failed, inconclusive)
870
891
  }
871
892
 
872
- private updateTestsTabLabel(passed: number, failed: number) {
893
+ private updateTestsTabLabel(
894
+ passed: number,
895
+ failed: number,
896
+ inconclusive = 0
897
+ ) {
873
898
  const tabs = this.parts.outputTabs
874
899
  if (!tabs) return
875
900
 
876
901
  if (failed > 0) {
877
902
  tabs.style.setProperty('--test-indicator-color', '#dc2626')
903
+ } else if (inconclusive > 0) {
904
+ tabs.style.setProperty('--test-indicator-color', '#d97706')
878
905
  } else if (passed > 0) {
879
906
  tabs.style.setProperty('--test-indicator-color', '#16a34a')
880
907
  } else {
@@ -1394,7 +1421,7 @@ export class TJSPlayground extends Component<TJSPlaygroundParts> {
1394
1421
  }
1395
1422
 
1396
1423
  // Navigate to a specific line in the source editor
1397
- goToSourceLine(line: number, column: number = 1) {
1424
+ goToSourceLine(line: number, column = 1) {
1398
1425
  this.parts.inputTabs.value = 0 // Switch to TJS tab (first tab)
1399
1426
  // Wait for tab switch and editor resize before scrolling
1400
1427
  setTimeout(() => {
@@ -0,0 +1,34 @@
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
+ }
@@ -0,0 +1,120 @@
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
+ }