tjs-lang 0.6.26 → 0.6.27
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/demo/docs.json +1 -1
- package/dist/bin/benchmarks.d.ts +9 -0
- package/dist/bin/dev.d.ts +1 -0
- package/dist/bin/docs.d.ts +1 -0
- package/dist/bin/select-local-models.d.ts +1 -0
- package/dist/examples/modules/dist/main.d.ts +34 -0
- package/dist/examples/modules/dist/math.d.ts +120 -0
- package/dist/index.js +423 -0
- package/dist/index.js.map +45 -0
- package/dist/scripts/build-demo.d.ts +2 -0
- package/dist/scripts/build.d.ts +11 -0
- package/dist/scripts/seed-blog-rules.d.ts +2 -0
- package/dist/scripts/seed-stored-function.d.ts +2 -0
- package/dist/src/atoms/batteries.d.ts +4 -0
- package/dist/src/atoms/browser.d.ts +4 -0
- package/dist/src/atoms/index.d.ts +4 -0
- package/dist/src/batteries/audit.d.ts +9 -0
- package/dist/src/batteries/index.d.ts +28 -0
- package/dist/src/batteries/llm.d.ts +18 -0
- package/dist/src/batteries/models.d.ts +19 -0
- package/dist/src/batteries/store.d.ts +13 -0
- package/dist/src/builder.d.ts +127 -0
- package/dist/src/bun-plugin/tjs-plugin.d.ts +12 -0
- package/dist/src/cli/commands/check.d.ts +4 -0
- package/dist/src/cli/commands/convert.d.ts +20 -0
- package/dist/src/cli/commands/emit.d.ts +34 -0
- package/dist/src/cli/commands/run.d.ts +6 -0
- package/dist/src/cli/commands/test.d.ts +21 -0
- package/dist/src/cli/commands/types.d.ts +4 -0
- package/dist/src/cli/create-app.d.ts +9 -0
- package/dist/src/cli/playground.d.ts +9 -0
- package/dist/src/cli/tjs.d.ts +15 -0
- package/dist/src/cli/tjsx.d.ts +16 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/inference.types.d.ts +1 -0
- package/dist/src/lang/core.d.ts +56 -0
- package/dist/src/lang/docs.d.ts +69 -0
- package/dist/src/lang/emitters/ast.d.ts +24 -0
- package/dist/src/lang/emitters/dts.d.ts +48 -0
- package/dist/src/lang/emitters/from-ts.d.ts +94 -0
- package/dist/src/lang/emitters/js-tests.d.ts +70 -0
- package/dist/src/lang/emitters/js-wasm.d.ts +15 -0
- package/dist/src/lang/emitters/js.d.ts +175 -0
- package/dist/src/lang/eval.d.ts +63 -0
- package/dist/src/lang/index.d.ts +216 -0
- package/dist/src/lang/inference.d.ts +40 -0
- package/dist/src/lang/linter.d.ts +53 -0
- package/dist/src/lang/metadata-cache.d.ts +172 -0
- package/dist/src/lang/parser-params.d.ts +37 -0
- package/dist/src/lang/parser-transforms.d.ts +281 -0
- package/dist/src/lang/parser-types.d.ts +175 -0
- package/dist/src/lang/parser.d.ts +56 -0
- package/dist/src/lang/runtime.d.ts +488 -0
- package/dist/src/lang/schema.d.ts +35 -0
- package/dist/src/lang/tests.d.ts +94 -0
- package/dist/src/lang/transpiler.d.ts +25 -0
- package/dist/src/lang/types.d.ts +147 -0
- package/dist/src/lang/wasm.d.ts +83 -0
- package/dist/src/rbac/index.d.ts +85 -0
- package/dist/src/rbac/rules.d.ts +184 -0
- package/dist/src/runtime.d.ts +4 -0
- package/dist/src/store/index.d.ts +3 -0
- package/dist/src/store/indexeddb.d.ts +6 -0
- package/dist/src/store/interface.d.ts +90 -0
- package/dist/src/store/memory.d.ts +10 -0
- package/dist/src/test-examples.d.ts +41 -0
- package/dist/src/test-utils.d.ts +86 -0
- package/dist/src/transpiler/index.d.ts +6 -0
- package/dist/src/transpiler/parser.d.ts +4 -0
- package/dist/src/transpiler/transformer.d.ts +4 -0
- package/dist/src/transpiler/type-system/inference.d.ts +1 -0
- package/dist/src/transpiler/types.d.ts +4 -0
- package/dist/src/types/LegalDate.d.ts +241 -0
- package/dist/src/types/Timestamp.d.ts +233 -0
- package/dist/src/types/Type.d.ts +234 -0
- package/dist/src/types/index.d.ts +8 -0
- package/dist/src/vm/atoms/batteries.d.ts +6 -0
- package/dist/src/vm/atoms/browser.d.ts +18 -0
- package/dist/src/vm/atoms/index.d.ts +10 -0
- package/dist/src/vm/index.d.ts +12 -0
- package/dist/src/vm/runtime.d.ts +333 -0
- package/dist/src/vm/vm.d.ts +28 -0
- package/dist/src/vm.d.ts +4 -0
- package/dist/test-preprocess.d.ts +1 -0
- package/dist/tjs-batteries.js +4 -0
- package/dist/tjs-batteries.js.map +15 -0
- package/dist/tjs-full.js +423 -0
- package/dist/tjs-full.js.map +45 -0
- package/dist/tjs-src/runtime.d.ts +1 -0
- package/dist/tjs-transpiler.js +3 -0
- package/dist/tjs-transpiler.js.map +11 -0
- package/dist/tjs-vm.js +54 -0
- package/dist/tjs-vm.js.map +22 -0
- package/package.json +1 -1
- package/src/cli/tjs.ts +1 -1
- package/src/lang/emitters/js.ts +3 -0
- package/src/lang/parser-transforms.ts +6 -0
- package/src/lang/roundtrip.test.ts +1 -1
- package/src/lang/runtime.ts +18 -1
- package/src/lang/wasm.ts +1 -1
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TJS Runtime
|
|
3
|
+
*
|
|
4
|
+
* Monadic type checking at runtime:
|
|
5
|
+
* - Functions validate inputs against __tjs metadata
|
|
6
|
+
* - If any input is an error, pass it through (no work)
|
|
7
|
+
* - Type mismatches return error objects
|
|
8
|
+
* - Errors propagate through call chains
|
|
9
|
+
*
|
|
10
|
+
* This runtime is attached to globalThis.__tjs and shared across modules.
|
|
11
|
+
*/
|
|
12
|
+
import { validate } from 'tosijs-schema';
|
|
13
|
+
import { Type, isRuntimeType, Union, Generic, Enum, FunctionPredicate, Nullable, Optional, TArray, TString, TNumber, TBoolean, TInteger, TPositiveInt, TNonEmptyString, TEmail, TUrl, TUuid, Timestamp, LegalDate, TPair, TRecord, isValidUrl, isValidTimestamp, isValidLegalDate } from '../types/Type';
|
|
14
|
+
export { Type, isRuntimeType, Union, Generic, Enum, FunctionPredicate, Nullable, Optional, TArray, TString, TNumber, TBoolean, TInteger, TPositiveInt, TNonEmptyString, TEmail, TUrl, TUuid, Timestamp, LegalDate, TPair, TRecord, isValidUrl, isValidTimestamp, isValidLegalDate, };
|
|
15
|
+
export declare const TJS_VERSION: string;
|
|
16
|
+
/**
|
|
17
|
+
* Well-known symbol for custom equality.
|
|
18
|
+
*
|
|
19
|
+
* Any object can implement `[tjsEquals](other)` to control how `==` / `Is()`
|
|
20
|
+
* compares it. Useful for Proxies that should delegate equality to their target.
|
|
21
|
+
*
|
|
22
|
+
* Priority: tjsEquals symbol → .Equals method → structural comparison
|
|
23
|
+
*/
|
|
24
|
+
export declare const tjsEquals: unique symbol;
|
|
25
|
+
/**
|
|
26
|
+
* Compare two version strings
|
|
27
|
+
* Returns: -1 if a < b, 0 if equal, 1 if a > b
|
|
28
|
+
*/
|
|
29
|
+
export declare function compareVersions(a: string, b: string): -1 | 0 | 1;
|
|
30
|
+
/**
|
|
31
|
+
* Check if two versions are compatible (same major version)
|
|
32
|
+
*/
|
|
33
|
+
export declare function versionsCompatible(a: string, b: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* MonadicError - Internal error type for monadic error propagation
|
|
36
|
+
*
|
|
37
|
+
* This extends Error so:
|
|
38
|
+
* 1. It's a real Error with proper stack traces
|
|
39
|
+
* 2. User code can't accidentally process it as data (unlike { $error: true })
|
|
40
|
+
* 3. It flows through function calls via instanceof checks
|
|
41
|
+
*
|
|
42
|
+
* NOT exported to user code - they just see Error instances.
|
|
43
|
+
*/
|
|
44
|
+
export declare class MonadicError extends Error {
|
|
45
|
+
/** Path where the error occurred, e.g., "src/file.ts:42:greet.name" */
|
|
46
|
+
readonly path: string;
|
|
47
|
+
/** Expected type */
|
|
48
|
+
readonly expected?: string;
|
|
49
|
+
/** Actual type received */
|
|
50
|
+
readonly actual?: string;
|
|
51
|
+
/** TJS call stack (only in debug mode) - shows source locations */
|
|
52
|
+
readonly callStack?: string[];
|
|
53
|
+
constructor(message: string, path: string, expected?: string, actual?: string, callStack?: string[]);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a type error for inline validation
|
|
57
|
+
*
|
|
58
|
+
* Called ONLY when a type check fails - no overhead on happy path.
|
|
59
|
+
* Returns a MonadicError that propagates through the call chain.
|
|
60
|
+
* In debug mode, captures the TJS call stack with source locations.
|
|
61
|
+
*
|
|
62
|
+
* @param path - Location of the error, e.g., "src/file.ts:42:greet.name"
|
|
63
|
+
* @param expected - Expected type, e.g., "string"
|
|
64
|
+
* @param value - The actual value that failed the check
|
|
65
|
+
*/
|
|
66
|
+
export declare function typeError(path: string, expected: string, value: unknown): MonadicError;
|
|
67
|
+
/**
|
|
68
|
+
* Check if a value is a MonadicError (for internal use)
|
|
69
|
+
*/
|
|
70
|
+
export declare function isMonadicError(value: unknown): value is MonadicError;
|
|
71
|
+
/**
|
|
72
|
+
* Error marker - identifies TJS error objects
|
|
73
|
+
* @deprecated Use MonadicError instead. This interface is kept for backward compatibility.
|
|
74
|
+
*/
|
|
75
|
+
export interface TJSError {
|
|
76
|
+
$error: true;
|
|
77
|
+
message: string;
|
|
78
|
+
/** Failure location - e.g., "greet.name" */
|
|
79
|
+
path?: string;
|
|
80
|
+
/** Call stack in debug mode - e.g., ["main", "processUser", "greet.name"] */
|
|
81
|
+
stack?: string[];
|
|
82
|
+
expected?: string;
|
|
83
|
+
actual?: string;
|
|
84
|
+
cause?: Error | TJSError;
|
|
85
|
+
/** Source location for error reporting */
|
|
86
|
+
loc?: {
|
|
87
|
+
start: number;
|
|
88
|
+
end: number;
|
|
89
|
+
};
|
|
90
|
+
/** Multiple errors (when composing parameter errors) */
|
|
91
|
+
errors?: TJSError[];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Safety levels for runtime validation
|
|
95
|
+
* - 'none': No validation unless explicitly forced with (?) or -?
|
|
96
|
+
* - 'inputs': Validate inputs only (default) - outputs only with explicit -> or -?
|
|
97
|
+
* - 'all': Validate both inputs and outputs unless explicitly skipped with (!) or -!
|
|
98
|
+
*/
|
|
99
|
+
export type SafetyLevel = 'none' | 'inputs' | 'all';
|
|
100
|
+
/**
|
|
101
|
+
* Runtime configuration
|
|
102
|
+
*/
|
|
103
|
+
export interface TJSConfig {
|
|
104
|
+
/** Enable debug mode - captures call stacks in errors */
|
|
105
|
+
debug?: boolean;
|
|
106
|
+
/** Safety level for validation (default: 'inputs') */
|
|
107
|
+
safety?: SafetyLevel;
|
|
108
|
+
/** Require explicit return types (error if -> not specified) */
|
|
109
|
+
requireReturnTypes?: boolean;
|
|
110
|
+
/** Maximum call stack size to prevent memory issues (default: 100) */
|
|
111
|
+
maxStackSize?: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Enter unsafe mode - disables validation for all wrapped function calls
|
|
115
|
+
* Can be nested (uses depth counter)
|
|
116
|
+
*/
|
|
117
|
+
export declare function enterUnsafe(): void;
|
|
118
|
+
/**
|
|
119
|
+
* Exit unsafe mode - re-enables validation when depth returns to 0
|
|
120
|
+
*/
|
|
121
|
+
export declare function exitUnsafe(): void;
|
|
122
|
+
/**
|
|
123
|
+
* Check if currently in unsafe mode
|
|
124
|
+
*/
|
|
125
|
+
export declare function isUnsafeMode(): boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Configure TJS runtime
|
|
128
|
+
*/
|
|
129
|
+
export declare function configure(options: TJSConfig): void;
|
|
130
|
+
/**
|
|
131
|
+
* Get current configuration
|
|
132
|
+
*/
|
|
133
|
+
export declare function getConfig(): TJSConfig;
|
|
134
|
+
/**
|
|
135
|
+
* Push a function onto the call stack (debug mode only)
|
|
136
|
+
* Respects maxStackSize to prevent unbounded memory growth
|
|
137
|
+
*/
|
|
138
|
+
export declare function pushStack(name: string): void;
|
|
139
|
+
/**
|
|
140
|
+
* Pop a function from the call stack (debug mode only)
|
|
141
|
+
*/
|
|
142
|
+
export declare function popStack(): void;
|
|
143
|
+
/**
|
|
144
|
+
* Get current call stack snapshot
|
|
145
|
+
*/
|
|
146
|
+
export declare function getStack(): string[];
|
|
147
|
+
/**
|
|
148
|
+
* Reset runtime state to defaults
|
|
149
|
+
*
|
|
150
|
+
* Resets: config, callStack, unsafeDepth
|
|
151
|
+
* Use this in test teardown to prevent state leaking between tests.
|
|
152
|
+
*/
|
|
153
|
+
export declare function resetRuntime(): void;
|
|
154
|
+
/**
|
|
155
|
+
* Structural equality - the == that works
|
|
156
|
+
*
|
|
157
|
+
* Rules:
|
|
158
|
+
* 1. If left has [tjsEquals], call left[tjsEquals](right)
|
|
159
|
+
* 2. If right has [tjsEquals], call right[tjsEquals](left)
|
|
160
|
+
* 3. If left has .Equals, call left.Equals(right)
|
|
161
|
+
* 4. If right has .Equals, call right.Equals(left)
|
|
162
|
+
* 5. Arrays/objects: recursive structural comparison
|
|
163
|
+
* 6. Primitives: strict equality (no coercion)
|
|
164
|
+
*
|
|
165
|
+
* Usage: `a Is b` transforms to `Is(a, b)`
|
|
166
|
+
*/
|
|
167
|
+
export declare function Is(a: unknown, b: unknown): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Structural inequality - the != that works
|
|
170
|
+
*
|
|
171
|
+
* Usage: `a IsNot b` transforms to `IsNot(a, b)`
|
|
172
|
+
*/
|
|
173
|
+
export declare function IsNot(a: unknown, b: unknown): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Honest equality — what == should have been.
|
|
176
|
+
*
|
|
177
|
+
* Like === but fixes the two remaining footguns:
|
|
178
|
+
* 1. Unwraps boxed primitives: new String('foo') Eq 'foo' → true
|
|
179
|
+
* 2. Nullish equality: null Eq undefined → true
|
|
180
|
+
*
|
|
181
|
+
* Does NOT do deep structural comparison on objects/arrays (that's O(n)).
|
|
182
|
+
* Use Is/IsNot for explicit structural comparison when you need it.
|
|
183
|
+
*
|
|
184
|
+
* Usage: `a == b` with TjsEquals transforms to `Eq(a, b)`
|
|
185
|
+
*/
|
|
186
|
+
/**
|
|
187
|
+
* Honest typeof — fixes `typeof null === 'object'`
|
|
188
|
+
*
|
|
189
|
+
* Returns `'null'` for null instead of `'object'`.
|
|
190
|
+
* All other values return the same as standard typeof.
|
|
191
|
+
*
|
|
192
|
+
* Usage: `typeof x` with TjsEquals transforms to `TypeOf(x)`
|
|
193
|
+
*/
|
|
194
|
+
export declare function TypeOf(value: unknown): string;
|
|
195
|
+
export declare function Eq(a: unknown, b: unknown): boolean;
|
|
196
|
+
/**
|
|
197
|
+
* Honest inequality — what != should have been.
|
|
198
|
+
*
|
|
199
|
+
* Usage: `a != b` with TjsEquals transforms to `NotEq(a, b)`
|
|
200
|
+
*/
|
|
201
|
+
export declare function NotEq(a: unknown, b: unknown): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Check if a value is a TJS error
|
|
204
|
+
*/
|
|
205
|
+
export declare function isError(value: unknown): value is TJSError;
|
|
206
|
+
/**
|
|
207
|
+
* Create a TJS error
|
|
208
|
+
* In debug mode, captures the current call stack
|
|
209
|
+
*/
|
|
210
|
+
export declare function error(message: string, details?: Partial<Omit<TJSError, '$error' | 'message'>>): TJSError;
|
|
211
|
+
/**
|
|
212
|
+
* Compose multiple errors into a single error
|
|
213
|
+
* Used when multiple parameters have errors
|
|
214
|
+
*/
|
|
215
|
+
export declare function composeErrors(errors: TJSError[], funcName?: string): TJSError;
|
|
216
|
+
/**
|
|
217
|
+
* Get the type of a value
|
|
218
|
+
*
|
|
219
|
+
* Enhanced typeof that handles:
|
|
220
|
+
* - null (returns 'null' not 'object')
|
|
221
|
+
* - undefined (returns 'undefined')
|
|
222
|
+
* - arrays (returns 'array' not 'object')
|
|
223
|
+
* - native/platform types (returns constructor name for objects)
|
|
224
|
+
*
|
|
225
|
+
* For objects, returns the constructor name which enables pragmatic
|
|
226
|
+
* native type checking (e.g., 'HTMLElement', 'Buffer', 'Event')
|
|
227
|
+
*/
|
|
228
|
+
export declare function typeOf(value: unknown): string;
|
|
229
|
+
/**
|
|
230
|
+
* Check if a value is an instance of a native/platform type by constructor name
|
|
231
|
+
*
|
|
232
|
+
* This enables pragmatic native type checking without shipping type definitions:
|
|
233
|
+
* - isNativeType(el, 'HTMLElement') - DOM element check
|
|
234
|
+
* - isNativeType(buf, 'Buffer') - Node.js Buffer check
|
|
235
|
+
* - isNativeType(evt, 'Event') - DOM Event check
|
|
236
|
+
* - isNativeType(map, 'Map') - Map instance check
|
|
237
|
+
*
|
|
238
|
+
* @param value - The value to check
|
|
239
|
+
* @param typeName - The constructor name to match (e.g., 'HTMLElement', 'Buffer')
|
|
240
|
+
* @returns true if value's constructor.name matches or is in prototype chain
|
|
241
|
+
*/
|
|
242
|
+
export declare function isNativeType(value: unknown, typeName: string): boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Check if a value matches an expected type
|
|
245
|
+
*
|
|
246
|
+
* @param value - The value to check
|
|
247
|
+
* @param expected - Either a string type name ('string', 'number', etc.)
|
|
248
|
+
* or a RuntimeType instance with .check() method
|
|
249
|
+
* @param path - Optional path for error messages
|
|
250
|
+
*/
|
|
251
|
+
export declare function checkType(value: unknown, expected: string | {
|
|
252
|
+
check: (v: unknown) => boolean;
|
|
253
|
+
description: string;
|
|
254
|
+
}, path?: string): TJSError | null;
|
|
255
|
+
/** Type specifier - either a string name or a RuntimeType */
|
|
256
|
+
type TypeSpec = string | {
|
|
257
|
+
check: (v: unknown) => boolean;
|
|
258
|
+
description: string;
|
|
259
|
+
};
|
|
260
|
+
/** Parameter metadata with optional location */
|
|
261
|
+
interface ParamMeta {
|
|
262
|
+
type: TypeSpec;
|
|
263
|
+
required: boolean;
|
|
264
|
+
default?: unknown;
|
|
265
|
+
loc?: {
|
|
266
|
+
start: number;
|
|
267
|
+
end: number;
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Validate function arguments against __tjs metadata
|
|
272
|
+
* Returns first error found, or null if all valid
|
|
273
|
+
*/
|
|
274
|
+
export declare function validateArgs(args: Record<string, unknown>, meta: {
|
|
275
|
+
params: Record<string, ParamMeta>;
|
|
276
|
+
}, funcName?: string): TJSError | null;
|
|
277
|
+
/**
|
|
278
|
+
* Function metadata with safety flags
|
|
279
|
+
*/
|
|
280
|
+
export interface FunctionMeta {
|
|
281
|
+
params: Record<string, any>;
|
|
282
|
+
returns?: {
|
|
283
|
+
type: any;
|
|
284
|
+
safe?: boolean;
|
|
285
|
+
defaults?: Record<string, unknown>;
|
|
286
|
+
};
|
|
287
|
+
/** Function marked with (!) - never validate inputs */
|
|
288
|
+
unsafe?: boolean;
|
|
289
|
+
/** Function marked with (?) - always validate inputs */
|
|
290
|
+
safe?: boolean;
|
|
291
|
+
/** Return type marked with -! - never validate output */
|
|
292
|
+
unsafeReturn?: boolean;
|
|
293
|
+
/** Return type marked with -? - always validate output */
|
|
294
|
+
safeReturn?: boolean;
|
|
295
|
+
/** Explicit function name for stack tracking (used when fn.name is empty) */
|
|
296
|
+
name?: string;
|
|
297
|
+
/** Polymorphic dispatcher — skip wrapping, dispatch handles validation */
|
|
298
|
+
polymorphic?: boolean;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Wrap a function with monadic type checking
|
|
302
|
+
*
|
|
303
|
+
* @param fn - The original function
|
|
304
|
+
* @param meta - The __tjs metadata
|
|
305
|
+
* @returns Wrapped function that validates inputs and propagates errors
|
|
306
|
+
*/
|
|
307
|
+
export declare function wrap<T extends (...args: any[]) => any>(fn: T, meta: FunctionMeta): T;
|
|
308
|
+
/**
|
|
309
|
+
* Wrap a class to make it callable without `new`
|
|
310
|
+
*
|
|
311
|
+
* In TJS, classes can be instantiated without the `new` keyword:
|
|
312
|
+
* const obj = MyClass(args) // equivalent to new MyClass(args)
|
|
313
|
+
*
|
|
314
|
+
* This eliminates a common source of errors where developers forget `new`.
|
|
315
|
+
* Using explicit `new` still works but should be flagged by the linter.
|
|
316
|
+
*/
|
|
317
|
+
export declare function wrapClass<T extends new (...args: any[]) => any>(cls: T): T & ((...args: ConstructorParameters<T>) => InstanceType<T>);
|
|
318
|
+
/**
|
|
319
|
+
* Create an isolated TJS runtime instance
|
|
320
|
+
*
|
|
321
|
+
* Each call returns a fresh runtime with its own:
|
|
322
|
+
* - config (debug, safety, etc.)
|
|
323
|
+
* - callStack
|
|
324
|
+
* - unsafeDepth
|
|
325
|
+
*
|
|
326
|
+
* The new instance inherits the current global config at creation time,
|
|
327
|
+
* but subsequent changes are isolated.
|
|
328
|
+
*
|
|
329
|
+
* Use this to prevent state leaking between transpiled modules.
|
|
330
|
+
*/
|
|
331
|
+
export declare function createRuntime(): {
|
|
332
|
+
version: string;
|
|
333
|
+
MonadicError: typeof MonadicError;
|
|
334
|
+
typeError: (path: string, expected: string, value: unknown) => MonadicError;
|
|
335
|
+
isMonadicError: typeof isMonadicError;
|
|
336
|
+
isError: typeof isError;
|
|
337
|
+
error: (message: string, details?: Partial<Omit<TJSError, "$error" | "message">>) => TJSError;
|
|
338
|
+
composeErrors: typeof composeErrors;
|
|
339
|
+
typeOf: typeof typeOf;
|
|
340
|
+
isNativeType: typeof isNativeType;
|
|
341
|
+
checkType: typeof checkType;
|
|
342
|
+
validateArgs: typeof validateArgs;
|
|
343
|
+
wrap: typeof wrap;
|
|
344
|
+
wrapClass: typeof wrapClass;
|
|
345
|
+
compareVersions: typeof compareVersions;
|
|
346
|
+
versionsCompatible: typeof versionsCompatible;
|
|
347
|
+
configure: (options: TJSConfig) => void;
|
|
348
|
+
getConfig: () => TJSConfig;
|
|
349
|
+
pushStack: (name: string) => void;
|
|
350
|
+
popStack: () => void;
|
|
351
|
+
getStack: () => string[];
|
|
352
|
+
resetRuntime: () => void;
|
|
353
|
+
enterUnsafe: () => void;
|
|
354
|
+
exitUnsafe: () => void;
|
|
355
|
+
isUnsafeMode: () => boolean;
|
|
356
|
+
validate: typeof validate;
|
|
357
|
+
infer: (value: any) => import("tosijs-schema").Base<any>;
|
|
358
|
+
Type: typeof Type;
|
|
359
|
+
isRuntimeType: typeof isRuntimeType;
|
|
360
|
+
Union: typeof Union;
|
|
361
|
+
Generic: typeof Generic;
|
|
362
|
+
Enum: typeof Enum;
|
|
363
|
+
FunctionPredicate: typeof FunctionPredicate;
|
|
364
|
+
Nullable: typeof Nullable;
|
|
365
|
+
Optional: typeof Optional;
|
|
366
|
+
TArray: typeof TArray;
|
|
367
|
+
TString: import("..").RuntimeType<string>;
|
|
368
|
+
TNumber: import("..").RuntimeType<number>;
|
|
369
|
+
TBoolean: import("..").RuntimeType<boolean>;
|
|
370
|
+
TInteger: import("..").RuntimeType<number>;
|
|
371
|
+
TPositiveInt: import("..").RuntimeType<number>;
|
|
372
|
+
TNonEmptyString: import("..").RuntimeType<string>;
|
|
373
|
+
TEmail: import("..").RuntimeType<string>;
|
|
374
|
+
TUrl: import("..").RuntimeType<string>;
|
|
375
|
+
TUuid: import("..").RuntimeType<string>;
|
|
376
|
+
TPair: import("..").GenericType<string[]>;
|
|
377
|
+
TRecord: import("..").GenericType<string[]>;
|
|
378
|
+
Is: typeof Is;
|
|
379
|
+
IsNot: typeof IsNot;
|
|
380
|
+
Eq: typeof Eq;
|
|
381
|
+
NotEq: typeof NotEq;
|
|
382
|
+
TypeOf: typeof TypeOf;
|
|
383
|
+
tjsEquals: symbol;
|
|
384
|
+
registerExtension: (typeName: string, methodName: string, fn: (...args: any[]) => any) => void;
|
|
385
|
+
resolveExtension: (value: unknown, methodName: string) => ((...args: any[]) => any) | undefined;
|
|
386
|
+
};
|
|
387
|
+
/** Type for runtime instances */
|
|
388
|
+
export type TJSRuntime = ReturnType<typeof createRuntime>;
|
|
389
|
+
/**
|
|
390
|
+
* TJS Runtime object - attached to globalThis.__tjs
|
|
391
|
+
*
|
|
392
|
+
* NOTE: This is a shared global instance. For isolated execution,
|
|
393
|
+
* use createRuntime() instead.
|
|
394
|
+
*/
|
|
395
|
+
export declare const runtime: {
|
|
396
|
+
version: string;
|
|
397
|
+
MonadicError: typeof MonadicError;
|
|
398
|
+
typeError: typeof typeError;
|
|
399
|
+
isMonadicError: typeof isMonadicError;
|
|
400
|
+
isError: typeof isError;
|
|
401
|
+
error: typeof error;
|
|
402
|
+
composeErrors: typeof composeErrors;
|
|
403
|
+
typeOf: typeof typeOf;
|
|
404
|
+
isNativeType: typeof isNativeType;
|
|
405
|
+
checkType: typeof checkType;
|
|
406
|
+
validateArgs: typeof validateArgs;
|
|
407
|
+
wrap: typeof wrap;
|
|
408
|
+
wrapClass: typeof wrapClass;
|
|
409
|
+
compareVersions: typeof compareVersions;
|
|
410
|
+
versionsCompatible: typeof versionsCompatible;
|
|
411
|
+
configure: typeof configure;
|
|
412
|
+
getConfig: typeof getConfig;
|
|
413
|
+
pushStack: typeof pushStack;
|
|
414
|
+
popStack: typeof popStack;
|
|
415
|
+
getStack: typeof getStack;
|
|
416
|
+
resetRuntime: typeof resetRuntime;
|
|
417
|
+
enterUnsafe: typeof enterUnsafe;
|
|
418
|
+
exitUnsafe: typeof exitUnsafe;
|
|
419
|
+
isUnsafeMode: typeof isUnsafeMode;
|
|
420
|
+
createRuntime: typeof createRuntime;
|
|
421
|
+
validate: typeof validate;
|
|
422
|
+
infer: (value: any) => import("tosijs-schema").Base<any>;
|
|
423
|
+
Type: typeof Type;
|
|
424
|
+
isRuntimeType: typeof isRuntimeType;
|
|
425
|
+
Union: typeof Union;
|
|
426
|
+
Generic: typeof Generic;
|
|
427
|
+
Enum: typeof Enum;
|
|
428
|
+
FunctionPredicate: typeof FunctionPredicate;
|
|
429
|
+
Nullable: typeof Nullable;
|
|
430
|
+
Optional: typeof Optional;
|
|
431
|
+
TArray: typeof TArray;
|
|
432
|
+
TString: import("..").RuntimeType<string>;
|
|
433
|
+
TNumber: import("..").RuntimeType<number>;
|
|
434
|
+
TBoolean: import("..").RuntimeType<boolean>;
|
|
435
|
+
TInteger: import("..").RuntimeType<number>;
|
|
436
|
+
TPositiveInt: import("..").RuntimeType<number>;
|
|
437
|
+
TNonEmptyString: import("..").RuntimeType<string>;
|
|
438
|
+
TEmail: import("..").RuntimeType<string>;
|
|
439
|
+
TUrl: import("..").RuntimeType<string>;
|
|
440
|
+
TUuid: import("..").RuntimeType<string>;
|
|
441
|
+
Timestamp: import("..").RuntimeType<string>;
|
|
442
|
+
LegalDate: import("..").RuntimeType<string>;
|
|
443
|
+
TPair: import("..").GenericType<string[]>;
|
|
444
|
+
TRecord: import("..").GenericType<string[]>;
|
|
445
|
+
Is: typeof Is;
|
|
446
|
+
IsNot: typeof IsNot;
|
|
447
|
+
Eq: typeof Eq;
|
|
448
|
+
NotEq: typeof NotEq;
|
|
449
|
+
TypeOf: typeof TypeOf;
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* Install runtime globally (idempotent, version-checked)
|
|
453
|
+
*
|
|
454
|
+
* Version handling:
|
|
455
|
+
* - Same version: reuse existing (no warning)
|
|
456
|
+
* - Compatible (same major): reuse existing, log info
|
|
457
|
+
* - Incompatible (different major): warn, use newer version
|
|
458
|
+
*/
|
|
459
|
+
export declare function installRuntime(): typeof runtime;
|
|
460
|
+
/**
|
|
461
|
+
* Generate runtime wrapper code for emitted JS
|
|
462
|
+
* Skips wrapping for unsafe functions (marked with !)
|
|
463
|
+
*/
|
|
464
|
+
export declare function emitRuntimeWrapper(funcName: string): string;
|
|
465
|
+
/**
|
|
466
|
+
* Generate class wrapper code for emitted JS
|
|
467
|
+
* Makes classes callable without `new` keyword
|
|
468
|
+
* Emits standalone JS - no runtime dependency
|
|
469
|
+
*/
|
|
470
|
+
export declare function emitClassWrapper(className: string): string;
|
|
471
|
+
/**
|
|
472
|
+
* Questions/Notes:
|
|
473
|
+
*
|
|
474
|
+
* Q1: Should wrap() be automatic or opt-in?
|
|
475
|
+
* Current: Must be explicitly wrapped
|
|
476
|
+
* Could: Auto-wrap all functions with __tjs metadata
|
|
477
|
+
*
|
|
478
|
+
* Q2: Performance overhead of validation?
|
|
479
|
+
* Need benchmarks comparing wrapped vs unwrapped
|
|
480
|
+
* Could have 'production' mode that skips validation
|
|
481
|
+
*
|
|
482
|
+
* Q3: Async function handling?
|
|
483
|
+
* wrap() should detect async and handle Promise returns
|
|
484
|
+
*
|
|
485
|
+
* Q4: Deep object validation?
|
|
486
|
+
* Currently only checks top-level type
|
|
487
|
+
* Could recursively validate object shapes
|
|
488
|
+
*/
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TJS Schema - Runtime type system for Typed JavaScript
|
|
3
|
+
*
|
|
4
|
+
* Builds on tosijs-schema to provide:
|
|
5
|
+
* - Schema(x) callable for inference by example
|
|
6
|
+
* - Schema.type(x) for "fixed typeof" (null returns 'null', not 'object')
|
|
7
|
+
* - All tosijs-schema methods (string, number, object, array, etc.)
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* Schema('hello') // Schema matching string
|
|
11
|
+
* Schema(42) // Schema matching number (integer)
|
|
12
|
+
* Schema(null) // Schema matching null
|
|
13
|
+
* Schema(undefined) // Schema matching undefined
|
|
14
|
+
* Schema([1, 2, 3]) // Schema matching array of integers
|
|
15
|
+
* Schema({name: 'Anne'}) // Schema matching object with name: string
|
|
16
|
+
*
|
|
17
|
+
* Schema.type(null) // 'null' (not 'object' like typeof)
|
|
18
|
+
* Schema.type(undefined) // 'undefined'
|
|
19
|
+
* Schema.type([]) // 'array' (not 'object' like typeof)
|
|
20
|
+
*
|
|
21
|
+
* Schema.null.validate(x) // true if x is null
|
|
22
|
+
* Schema.undefined.validate(x) // true if x is undefined
|
|
23
|
+
*/
|
|
24
|
+
import { s, type Base } from 'tosijs-schema';
|
|
25
|
+
type SchemaCallable = {
|
|
26
|
+
(value: unknown): Base<unknown>;
|
|
27
|
+
type: (value: unknown) => string;
|
|
28
|
+
infer: (value: unknown) => Base<unknown>;
|
|
29
|
+
} & typeof s;
|
|
30
|
+
/**
|
|
31
|
+
* Schema - callable for inference, with all tosijs-schema methods attached
|
|
32
|
+
* Uses a Proxy to delegate property access to tosijs-schema's s object
|
|
33
|
+
*/
|
|
34
|
+
export declare const Schema: SchemaCallable;
|
|
35
|
+
export type { Base, Infer } from 'tosijs-schema';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TJS Inline Tests
|
|
3
|
+
*
|
|
4
|
+
* Extracts test blocks from TJS source and generates test runners.
|
|
5
|
+
*
|
|
6
|
+
* Syntax (TJS):
|
|
7
|
+
* test 'description' {
|
|
8
|
+
* assert(condition)
|
|
9
|
+
* expect(a).toBe(b)
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* test {
|
|
13
|
+
* // Anonymous test
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* mock {
|
|
17
|
+
* // Setup code that runs before each test
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* Syntax (TypeScript - embedded in comments):
|
|
21
|
+
* /*test 'description' {
|
|
22
|
+
* expect(add(2, 3)).toBe(5)
|
|
23
|
+
* }* /
|
|
24
|
+
*
|
|
25
|
+
* This syntax survives TypeScript compilation, enabling literate
|
|
26
|
+
* programming for TypeScript: tests live alongside the code they
|
|
27
|
+
* verify, extracted and executed at runtime by TJS.
|
|
28
|
+
*
|
|
29
|
+
* For TS developers who don't care about TJS: you still get inline
|
|
30
|
+
* tests that live with your code, literate development, and faster
|
|
31
|
+
* debug loops. Set `safety none` and keep living in your world.
|
|
32
|
+
*
|
|
33
|
+
* Output:
|
|
34
|
+
* - code: Clean source with tests stripped
|
|
35
|
+
* - tests: Array of extracted test definitions
|
|
36
|
+
* - testRunner: Generated code to execute tests
|
|
37
|
+
*/
|
|
38
|
+
export interface ExtractedTest {
|
|
39
|
+
description: string;
|
|
40
|
+
body: string;
|
|
41
|
+
line?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface ExtractedMock {
|
|
44
|
+
body: string;
|
|
45
|
+
line?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface TestExtractionResult {
|
|
48
|
+
/** Source code with tests and mocks removed */
|
|
49
|
+
code: string;
|
|
50
|
+
/** Extracted test definitions */
|
|
51
|
+
tests: ExtractedTest[];
|
|
52
|
+
/** Extracted mock/setup blocks */
|
|
53
|
+
mocks: ExtractedMock[];
|
|
54
|
+
/** Generated test runner code */
|
|
55
|
+
testRunner: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Extract inline tests from TJS source
|
|
59
|
+
*
|
|
60
|
+
* Note: Signature tests (from -> return types) are handled separately by the
|
|
61
|
+
* transpiler in js.ts. This function only extracts explicit test blocks.
|
|
62
|
+
*/
|
|
63
|
+
export declare function extractTests(source: string): TestExtractionResult;
|
|
64
|
+
/**
|
|
65
|
+
* Test utilities - assert and expect
|
|
66
|
+
* Include this in the runtime or inject it
|
|
67
|
+
*/
|
|
68
|
+
export declare const assertFunction = "\nfunction assert(condition, message) {\n if (!condition) {\n throw new Error(message || 'Assertion failed')\n }\n}\n";
|
|
69
|
+
/**
|
|
70
|
+
* Expect API for richer test assertions
|
|
71
|
+
* Uses deep equality, handles null/undefined correctly
|
|
72
|
+
*/
|
|
73
|
+
export declare const expectFunction = "\nfunction expect(actual) {\n const deepEqual = (a, b) => {\n if (a === b) return true\n if (a === null || b === null) return a === b\n if (a === undefined || b === undefined) return a === undefined && b === undefined\n if (typeof a !== typeof b) return false\n if (typeof a !== 'object') return a === b\n if (Array.isArray(a) !== Array.isArray(b)) return false\n if (Array.isArray(a)) {\n if (a.length !== b.length) return false\n return a.every((v, i) => deepEqual(v, b[i]))\n }\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n if (keysA.length !== keysB.length) return false\n return keysA.every(k => deepEqual(a[k], b[k]))\n }\n\n const format = (v) => {\n if (v === null) return 'null'\n if (v === undefined) return 'undefined'\n if (typeof v === 'string') return JSON.stringify(v)\n if (typeof v === 'object') return JSON.stringify(v)\n return String(v)\n }\n\n return {\n toBe(expected) {\n if (!deepEqual(actual, expected)) {\n throw new Error(`Expected ${format(expected)} but got ${format(actual)}`)\n }\n },\n toEqual(expected) {\n if (!deepEqual(actual, expected)) {\n throw new Error(`Expected ${format(expected)} but got ${format(actual)}`)\n }\n },\n toContain(item) {\n if (!Array.isArray(actual) || !actual.some(v => deepEqual(v, item))) {\n throw new Error(`Expected ${format(actual)} to contain ${format(item)}`)\n }\n },\n toThrow(message) {\n let threw = false\n let thrownMessage = ''\n try {\n if (typeof actual === 'function') actual()\n } catch (e) {\n threw = true\n thrownMessage = e.message || String(e)\n }\n if (!threw) {\n throw new Error('Expected function to throw but it did not')\n }\n if (message && !thrownMessage.includes(message)) {\n throw new Error(`Expected error containing \"${message}\" but got \"${thrownMessage}\"`)\n }\n },\n toBeTruthy() {\n if (!actual) {\n throw new Error(`Expected ${format(actual)} to be truthy`)\n }\n },\n toBeFalsy() {\n if (actual) {\n throw new Error(`Expected ${format(actual)} to be falsy`)\n }\n },\n toBeNull() {\n if (actual !== null) {\n throw new Error(`Expected null but got ${format(actual)}`)\n }\n },\n toBeUndefined() {\n if (actual !== undefined) {\n throw new Error(`Expected undefined but got ${format(actual)}`)\n }\n },\n toBeGreaterThan(n) {\n if (!(actual > n)) {\n throw new Error(`Expected ${format(actual)} to be greater than ${n}`)\n }\n },\n toBeLessThan(n) {\n if (!(actual < n)) {\n throw new Error(`Expected ${format(actual)} to be less than ${n}`)\n }\n }\n }\n}\n";
|
|
74
|
+
/**
|
|
75
|
+
* Combined test utilities (assert + expect)
|
|
76
|
+
*/
|
|
77
|
+
export declare const testUtils: string;
|
|
78
|
+
/**
|
|
79
|
+
* Questions/Notes:
|
|
80
|
+
*
|
|
81
|
+
* Q1: Should mocks be scoped per-test or shared?
|
|
82
|
+
* Current: Each test runs all mocks before executing
|
|
83
|
+
*
|
|
84
|
+
* Q2: Should we support test.only / test.skip?
|
|
85
|
+
* Easy to add with syntax: test.only('...') { } or test.skip('...') { }
|
|
86
|
+
*
|
|
87
|
+
* Q3: Integration with playground?
|
|
88
|
+
* Playground could run extractTests() and show test results in a panel
|
|
89
|
+
*
|
|
90
|
+
* Q4: DOM tests - test.browser('desc') { }?
|
|
91
|
+
* SHELVED: Plan is to run tests in actual browser (playground)
|
|
92
|
+
* Happy-DOM is ~1MB packed, too heavy to bundle
|
|
93
|
+
* If needed later: lazy-load happy-dom only for Node/Bun DOM tests
|
|
94
|
+
*/
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TJS Transpiler - Core transpilation without TS compiler
|
|
3
|
+
*
|
|
4
|
+
* This is the lightweight entry point for TJS/AJS transpilation.
|
|
5
|
+
* Does NOT include fromTS (which requires the full TypeScript compiler).
|
|
6
|
+
*
|
|
7
|
+
* For TS -> TJS conversion, use the full bundle or import fromTS separately.
|
|
8
|
+
*
|
|
9
|
+
* NOTE: We import directly from source files, NOT from ./index, because
|
|
10
|
+
* ./index imports from-ts.ts which pulls in the TypeScript compiler (~4MB).
|
|
11
|
+
*/
|
|
12
|
+
export { transpile, ajs, tjs, createAgent, getToolDefinitions } from './core';
|
|
13
|
+
export { parse, preprocess, extractTDoc } from './parser';
|
|
14
|
+
export { transformFunction } from './emitters/ast';
|
|
15
|
+
export { transpileToJS } from './emitters/js';
|
|
16
|
+
export type { TJSTranspileOptions, TJSTranspileResult, TJSTypeInfo, } from './emitters/js';
|
|
17
|
+
export * from './inference';
|
|
18
|
+
export { Schema } from './schema';
|
|
19
|
+
export { lint } from './linter';
|
|
20
|
+
export type { LintResult, LintDiagnostic, LintOptions } from './linter';
|
|
21
|
+
export { extractTests, assertFunction, expectFunction, testUtils, } from './tests';
|
|
22
|
+
export type { ExtractedTest, ExtractedMock, TestExtractionResult, } from './tests';
|
|
23
|
+
export { runtime, installRuntime, isError, error, typeOf, checkType, validateArgs, wrap, emitRuntimeWrapper, TJS_VERSION, } from './runtime';
|
|
24
|
+
export type { TJSError } from './runtime';
|
|
25
|
+
export type { TypeDescriptor, ParameterDescriptor, FunctionSignature, TranspileOptions, TranspileResult, TranspileWarning, } from './types';
|