tjs-lang 0.6.26 → 0.6.28
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 +37 -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
package/demo/docs.json
CHANGED
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"type": "example",
|
|
116
116
|
"group": "basics",
|
|
117
117
|
"order": 15,
|
|
118
|
-
"code": "TjsEquals\n\n/*#\n## The Problem with JavaScript ==\n\nJavaScript's `==` does type coercion, producing surprises:\n\n 0 == '' // true in JS (!)\n false == [] // true in JS (!)\n '' == false // true in JS (!)\n null == 0 // false in JS (but null == undefined is true)\n\nJavaScript's `===` fixes coercion but can't compare values:\n\n new String('hi') === 'hi' // false in JS (different types)\n new Boolean(false) === false // false in JS (object vs primitive)\n\n## TJS Equality (TjsEquals)\n\n`==` becomes **honest equality**: no coercion, but unwraps\nboxed primitives. Fast O(1) — no deep comparison.\n\n`Is` / `IsNot` are **structural equality**: deep comparison\nfor when you explicitly need it. O(n) cost is visible.\n*/\n\n// --- Honest equality (==) fixes coercion ---\nconsole.log('== fixes JS coercion:')\nconsole.log(' 0 == \"\":', 0 == '') // false (JS: true)\nconsole.log(' false == []:', false == []) // false (JS: true)\nconsole.log(' false == \"\":', false == '') // false (JS: true)\nconsole.log(' 1 == \"1\":', 1 == '1') // false (JS: true)\n\n// --- Boxed primitives unwrap ---\nconsole.log('')\nconsole.log('== unwraps boxed primitives:')\nconsole.log(' new String(\"hi\") == \"hi\":', new String('hi') == 'hi') // true\nconsole.log(' new Boolean(false) == false:', new Boolean(false) == false) // true\nconsole.log(' new Number(42) == 42:', new Number(42) == 42) // true\n\n// --- Nullish equality preserved ---\nconsole.log('')\nconsole.log('Nullish equality (useful pattern preserved):')\nconsole.log(' null == undefined:', null == undefined) // true\nconsole.log(' null == 0:', null == 0) // false\nconsole.log(' null == \"\":', null == '') // false\n\n// --- Objects/arrays: reference equality (fast, O(1)) ---\nconsole.log('')\nconsole.log('== on objects/arrays is reference equality (fast):')\nconst obj = {x: 1}\nconsole.log(' obj == obj:', obj == obj) // true (same ref)\nconsole.log(' {x:1} == {x:1}:', {x: 1} == {x: 1}) // false (different refs)\nconsole.log(' [1,2] == [1,2]:', [1, 2] == [1, 2]) // false (different refs)\n\n// --- Is/IsNot: explicit deep structural comparison ---\nconsole.log('')\nconsole.log('Is/IsNot for deep structural comparison (explicit):')\nconsole.log(' {x:1} Is {x:1}:', Is({x: 1}, {x: 1})) // true\nconsole.log(' [1,2,3] Is [1,2,3]:', Is([1,2,3], [1,2,3])) // true\nconsole.log(' [1,2] Is [2,1]:', Is([1,2], [2,1])) // false (order matters)\n\n// Sets compare by membership, not order\nconsole.log(' Set([1,2]) Is Set([2,1]):', Is(new Set([1,2]), new Set([2,1]))) // true\n\n// --- === unchanged: identity comparison ---\nconsole.log('')\nconsole.log('=== is unchanged (identity):')\nconsole.log(' obj === obj:', obj === obj) // true\nconsole.log(' {x:1} === {x:1}:', {x: 1} === {x: 1}) // false\n\ntest 'Eq fixes coercion' {\n expect(Eq(0, '')).toBe(false)\n expect(Eq(false, [])).toBe(false)\n expect(Eq('', false)).toBe(false)\n}\n\ntest 'Eq unwraps boxed primitives' {\n expect(Eq(new String('hi'), 'hi')).toBe(true)\n expect(Eq(new Boolean(false), false)).toBe(true)\n expect(Eq(new Number(42), 42)).toBe(true)\n}\n\ntest 'Eq preserves nullish equality' {\n expect(Eq(null, undefined)).toBe(true)\n expect(Eq(null, 0)).toBe(false)\n}\n\ntest 'Is does deep structural comparison' {\n expect(Is({a: 1, b: 2}, {a: 1, b: 2})).toBe(true)\n expect(Is([1, 2, 3], [1, 2, 3])).toBe(true)\n expect(Is([1, 2], [2, 1])).toBe(false)\n}",
|
|
118
|
+
"code": "TjsEquals\n\n/*#\n## The Problem with JavaScript ==\n\nJavaScript's `==` does type coercion, producing surprises:\n\n 0 == '' // true in JS (!)\n false == [] // true in JS (!)\n '' == false // true in JS (!)\n null == 0 // false in JS (but null == undefined is true)\n\nJavaScript's `===` fixes coercion but can't compare values:\n\n new String('hi') === 'hi' // false in JS (different types)\n new Boolean(false) === false // false in JS (object vs primitive)\n\n## TJS Equality (TjsEquals)\n\n`==` becomes **honest equality**: no coercion, but unwraps\nboxed primitives. Fast O(1) — no deep comparison.\n\n`Is` / `IsNot` are **structural equality**: deep comparison\nfor when you explicitly need it. O(n) cost is visible.\n*/\n\n// --- Honest equality (==) fixes coercion ---\nconsole.log('== fixes JS coercion:')\nconsole.log(' [] == ![]:', [] == ![]) // false (JS: true!)\nconsole.log(' 0 == \"\":', 0 == '') // false (JS: true)\nconsole.log(' false == []:', false == []) // false (JS: true)\nconsole.log(' false == \"\":', false == '') // false (JS: true)\nconsole.log(' 1 == \"1\":', 1 == '1') // false (JS: true)\n\n// --- Boxed primitives unwrap ---\nconsole.log('')\nconsole.log('== unwraps boxed primitives:')\nconsole.log(' new String(\"hi\") == \"hi\":', new String('hi') == 'hi') // true\nconsole.log(' new Boolean(false) == false:', new Boolean(false) == false) // true\nconsole.log(' new Number(42) == 42:', new Number(42) == 42) // true\n\n// --- Nullish equality preserved ---\nconsole.log('')\nconsole.log('Nullish equality (useful pattern preserved):')\nconsole.log(' null == undefined:', null == undefined) // true\nconsole.log(' null == 0:', null == 0) // false\nconsole.log(' null == \"\":', null == '') // false\n\n// --- Objects/arrays: reference equality (fast, O(1)) ---\nconsole.log('')\nconsole.log('== on objects/arrays is reference equality (fast):')\nconst obj = {x: 1}\nconsole.log(' obj == obj:', obj == obj) // true (same ref)\nconsole.log(' {x:1} == {x:1}:', {x: 1} == {x: 1}) // false (different refs)\nconsole.log(' [1,2] == [1,2]:', [1, 2] == [1, 2]) // false (different refs)\n\n// --- Is/IsNot: explicit deep structural comparison ---\nconsole.log('')\nconsole.log('Is/IsNot for deep structural comparison (explicit):')\nconsole.log(' {x:1} Is {x:1}:', Is({x: 1}, {x: 1})) // true\nconsole.log(' [1,2,3] Is [1,2,3]:', Is([1,2,3], [1,2,3])) // true\nconsole.log(' [1,2] Is [2,1]:', Is([1,2], [2,1])) // false (order matters)\n\n// Sets compare by membership, not order\nconsole.log(' Set([1,2]) Is Set([2,1]):', Is(new Set([1,2]), new Set([2,1]))) // true\n\n// --- typeof null fixed ---\nconsole.log('')\nconsole.log('typeof null fixed:')\nconsole.log(' typeof null:', typeof null) // 'null' (JS: 'object')\nconsole.log(' typeof undefined:', typeof undefined) // 'undefined'\nconsole.log(' typeof 42:', typeof 42) // 'number' (unchanged)\n\n// --- === unchanged: identity comparison ---\nconsole.log('')\nconsole.log('=== is unchanged (identity):')\nconsole.log(' obj === obj:', obj === obj) // true\nconsole.log(' {x:1} === {x:1}:', {x: 1} === {x: 1}) // false\n\ntest 'typeof null is null, not object' {\n expect(TypeOf(null)).toBe('null')\n expect(TypeOf(undefined)).toBe('undefined')\n expect(TypeOf(42)).toBe('number')\n expect(TypeOf('hi')).toBe('string')\n expect(TypeOf(true)).toBe('boolean')\n expect(TypeOf({})).toBe('object')\n}\n\ntest 'Eq fixes coercion' {\n expect(Eq(0, '')).toBe(false)\n expect(Eq(false, [])).toBe(false)\n expect(Eq('', false)).toBe(false)\n}\n\ntest 'Eq unwraps boxed primitives' {\n expect(Eq(new String('hi'), 'hi')).toBe(true)\n expect(Eq(new Boolean(false), false)).toBe(true)\n expect(Eq(new Number(42), 42)).toBe(true)\n}\n\ntest 'Eq preserves nullish equality' {\n expect(Eq(null, undefined)).toBe(true)\n expect(Eq(null, 0)).toBe(false)\n}\n\ntest 'Is does deep structural comparison' {\n expect(Is({a: 1, b: 2}, {a: 1, b: 2})).toBe(true)\n expect(Is([1, 2, 3], [1, 2, 3])).toBe(true)\n expect(Is([1, 2], [2, 1])).toBe(false)\n}",
|
|
119
119
|
"language": "tjs",
|
|
120
120
|
"description": "JavaScript `==` is broken. TJS fixes it without breaking anything."
|
|
121
121
|
},
|
|
@@ -357,6 +357,42 @@
|
|
|
357
357
|
"language": "tjs",
|
|
358
358
|
"description": "Named types with runtime validation. Type, Generic, FunctionPredicate, Enum, Union."
|
|
359
359
|
},
|
|
360
|
+
{
|
|
361
|
+
"title": "Inline WASM",
|
|
362
|
+
"filename": "wasm-basics.md",
|
|
363
|
+
"path": "guides/examples/tjs/wasm-basics.md",
|
|
364
|
+
"section": "tjs",
|
|
365
|
+
"type": "example",
|
|
366
|
+
"group": "patterns",
|
|
367
|
+
"order": 25,
|
|
368
|
+
"code": "/*#\n## The Problem\n\nUsing WebAssembly in JavaScript requires:\n1. Write WAT or compile from C/Rust\n2. Load a separate .wasm file\n3. Instantiate the module async\n4. Marshal data between JS and WASM heaps\n\nTJS does all of this for you. Write WASM inline using JS-like\nsyntax, it compiles at transpile time and embeds as base64.\n\n## Syntax\n\n function fast(x: 0, y: 0) {\n wasm {\n // JS-like syntax compiled to WASM bytecode\n } fallback {\n // JS fallback if WASM unavailable\n return x + y\n }\n }\n\n // Or with a return value:\n function compute(x: 0) {\n return wasm {\n x * x + 1\n } fallback {\n return x * x + 1\n }\n }\n\nParam types: `i32` (integer), `f32`/`f64` (float), `Float32Array`, etc.\n*/\n\n// --- Basic: integer math in WASM ---\n\nfunction addInts(! a: 0, b: 0) -! 0 {\n return wasm {\n a + b\n } fallback {\n return a + b\n }\n}\n\nfunction factorial(! n: 0) -! 0 {\n return wasm {\n let result = 1\n for (let i = 2; i <= n; i++) {\n result = result * i\n }\n } fallback {\n let result = 1\n for (let i = 2; i <= n; i++) result *= i\n return result\n }\n}\n\n// --- Float math ---\n\nfunction lerp(! a: 0.0, b: 0.0, t: 0.0) -! 0.0 {\n return wasm {\n a + (b - a) * t\n } fallback {\n return a + (b - a) * t\n }\n}\n\n// --- Array processing ---\n\nfunction sumArray(! arr: Float32Array, len: 0) -! 0.0 {\n return wasm {\n let sum = 0.0\n for (let i = 0; i < len; i++) {\n let off = i * 4\n sum = sum + f32x4_extract_lane(f32x4_load(arr, off), 0)\n }\n } fallback {\n let sum = 0\n for (let i = 0; i < len; i++) sum += arr[i]\n return sum\n }\n}\n\nconsole.log('addInts(3, 4):', addInts(3, 4))\nconsole.log('factorial(10):', factorial(10))\nconsole.log('lerp(0, 100, 0.25):', lerp(0.0, 100.0, 0.25))\nconsole.log('sumArray([1,2,3,4]):', sumArray(new Float32Array([1, 2, 3, 4]), 4))",
|
|
369
|
+
"language": "tjs",
|
|
370
|
+
"description": "Write WebAssembly inline — compiled at transpile time, embedded in the output."
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"title": "WASM SIMD",
|
|
374
|
+
"filename": "wasm-simd.md",
|
|
375
|
+
"path": "guides/examples/tjs/wasm-simd.md",
|
|
376
|
+
"section": "tjs",
|
|
377
|
+
"type": "example",
|
|
378
|
+
"group": "patterns",
|
|
379
|
+
"order": 26,
|
|
380
|
+
"code": "/*#\n## SIMD: Single Instruction, Multiple Data\n\nSIMD processes 4 float values per instruction — a 4x throughput\nimprovement for vectorized math. TJS provides SIMD via `f32x4_*`\nintrinsics that compile directly to WASM SIMD opcodes.\n\n### Available Intrinsics\n\n| Intrinsic | Operation |\n|-----------|-----------|\n| `f32x4_load(arr, offset)` | Load 4 floats from array |\n| `f32x4_store(arr, offset, vec)` | Store 4 floats to array |\n| `f32x4_splat(value)` | Fill all 4 lanes with one value |\n| `f32x4_add(a, b)` | Add 4 pairs |\n| `f32x4_sub(a, b)` | Subtract 4 pairs |\n| `f32x4_mul(a, b)` | Multiply 4 pairs |\n| `f32x4_div(a, b)` | Divide 4 pairs |\n| `f32x4_neg(a)` | Negate 4 values |\n| `f32x4_sqrt(a)` | Square root of 4 values |\n| `f32x4_extract_lane(vec, lane)` | Get one float (0-3) |\n| `f32x4_replace_lane(vec, lane, val)` | Set one float |\n*/\n\n// --- Scale an array by a constant (SIMD: 4 elements per step) ---\n\nfunction scale(! arr: Float32Array, len: 0, factor: 0.0) {\n wasm {\n let s = f32x4_splat(factor)\n for (let i = 0; i < len; i += 4) {\n let off = i * 4\n let v = f32x4_load(arr, off)\n f32x4_store(arr, off, f32x4_mul(v, s))\n }\n } fallback {\n for (let i = 0; i < len; i++) arr[i] *= factor\n }\n}\n\n// --- Dot product (sum of element-wise products) ---\n\nfunction dot(! a: Float32Array, b: Float32Array, len: 0) -! 0.0 {\n return wasm {\n let acc = f32x4_splat(0.0)\n for (let i = 0; i < len; i += 4) {\n let off = i * 4\n let va = f32x4_load(a, off)\n let vb = f32x4_load(b, off)\n acc = f32x4_add(acc, f32x4_mul(va, vb))\n }\n // Sum the 4 lanes\n f32x4_extract_lane(acc, 0)\n + f32x4_extract_lane(acc, 1)\n + f32x4_extract_lane(acc, 2)\n + f32x4_extract_lane(acc, 3)\n } fallback {\n let sum = 0\n for (let i = 0; i < len; i++) sum += a[i] * b[i]\n return sum\n }\n}\n\n// --- Demo ---\n\nconst SIZE = 1024\n\n// Create test arrays\nconst arr = new Float32Array(SIZE)\nconst a = new Float32Array(SIZE)\nconst b = new Float32Array(SIZE)\n\nfor (let i = 0; i < SIZE; i++) {\n arr[i] = i + 1\n a[i] = 1.0\n b[i] = 2.0\n}\n\n// Scale\nscale(arr, SIZE, 0.5)\nconsole.log('scale([1..1024], 0.5) first 4:', arr[0], arr[1], arr[2], arr[3])\n\n// Dot product: 1.0 * 2.0 * 1024 = 2048\nconst d = dot(a, b, SIZE)\nconsole.log('dot([1,1,...], [2,2,...], 1024):', d)\n\n// Benchmark\nconst iters = 1000\nconst t0 = performance.now()\nfor (let i = 0; i < iters; i++) scale(arr, SIZE, 1.001)\nconst elapsed = performance.now() - t0\nconsole.log(`${iters} scale ops on ${SIZE} floats: ${elapsed.toFixed(1)}ms`)",
|
|
381
|
+
"language": "tjs",
|
|
382
|
+
"description": "Process 4 floats per instruction. No setup, no toolchain."
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"title": "WASM Memory",
|
|
386
|
+
"filename": "wasm-memory.md",
|
|
387
|
+
"path": "guides/examples/tjs/wasm-memory.md",
|
|
388
|
+
"section": "tjs",
|
|
389
|
+
"type": "example",
|
|
390
|
+
"group": "patterns",
|
|
391
|
+
"order": 27,
|
|
392
|
+
"code": "/*#\n## How Data Moves Between JS and WASM\n\nThe #1 WebAssembly question: \"How do I get my data into WASM?\"\nTJS handles it automatically. Three modes:\n\n### 1. Scalars — pass through\n`i32`, `f32`, `f64` go directly as WASM parameters. No marshaling.\n\n### 2. Regular typed arrays — transparent copy\nPass a normal `Float32Array` and TJS copies it into WASM memory\nbefore the call, then copies results back out after. You don't\nhave to think about it.\n\n### 3. `wasmBuffer()` — zero-copy shared memory\nAllocate directly in WASM memory. Both JS and WASM see the same\nbytes. No copy in, no copy out. Mutations are instantly visible.\n\n const xs = wasmBuffer(Float32Array, 50000)\n xs[0] = 3.14 // JS writes to WASM memory\n wasmFunction(xs) // WASM reads/writes the same memory\n console.log(xs[0]) // JS sees WASM's mutations immediately\n\n### Supported types\n`Float32Array`, `Float64Array`, `Int32Array`, `Uint8Array`\n\n### How it works internally\nAll WASM blocks in a file share one `WebAssembly.Memory` (64MB).\n`wasmBuffer` is a bump allocator — it hands out slices of this memory.\nWhen a typed array argument's `.buffer === wasmMemory.buffer`, the\nwrapper skips the copy and passes the byte offset directly.\n*/\n\n// --- Regular arrays: transparent copy ---\n\nfunction addOne(! arr: Float32Array, len: 0) {\n wasm {\n for (let i = 0; i < len; i += 4) {\n let off = i * 4\n let v = f32x4_load(arr, off)\n let ones = f32x4_splat(1.0)\n f32x4_store(arr, off, f32x4_add(v, ones))\n }\n } fallback {\n for (let i = 0; i < len; i++) arr[i] += 1\n }\n}\n\n// Regular Float32Array — TJS copies in before, copies out after\nconst regular = new Float32Array([10, 20, 30, 40])\naddOne(regular, 4)\nconsole.log('Regular array after WASM:', Array.from(regular))\n// [11, 21, 31, 41] — changes visible in JS\n\n// --- wasmBuffer: zero-copy shared memory ---\n\nconst shared = wasmBuffer(Float32Array, 4)\nshared[0] = 100\nshared[1] = 200\nshared[2] = 300\nshared[3] = 400\n\naddOne(shared, 4)\nconsole.log('wasmBuffer after WASM:', Array.from(shared))\n// [101, 201, 301, 401] — zero copy, same memory\n\n// --- Practical: large array processing ---\n\nconst SIZE = 10000\nconst data = wasmBuffer(Float32Array, SIZE)\nfor (let i = 0; i < SIZE; i++) data[i] = i * 0.01\n\n// Process in WASM — no marshaling overhead\nfunction normalize(! arr: Float32Array, len: 0) {\n wasm {\n // Find max (scalar — SIMD max needs horizontal reduction)\n let max = 0.0\n for (let i = 0; i < len; i++) {\n let off = i * 4\n let v = f32x4_extract_lane(f32x4_load(arr, off), 0)\n if (v > max) { max = v }\n }\n // Scale to [0, 1]\n if (max > 0.0) {\n let inv = f32x4_splat(1.0 / max)\n for (let i = 0; i < len; i += 4) {\n let off = i * 4\n f32x4_store(arr, off, f32x4_mul(f32x4_load(arr, off), inv))\n }\n }\n } fallback {\n let max = 0\n for (let i = 0; i < len; i++) if (arr[i] > max) max = arr[i]\n if (max > 0) for (let i = 0; i < len; i++) arr[i] /= max\n }\n}\n\nconst t0 = performance.now()\nnormalize(data, SIZE)\nconst elapsed = performance.now() - t0\n\nconsole.log(`Normalized ${SIZE} floats in ${elapsed.toFixed(2)}ms`)\nconsole.log('First 4:', data[0].toFixed(4), data[1].toFixed(4), data[2].toFixed(4), data[3].toFixed(4))\nconsole.log('Last:', data[SIZE - 1].toFixed(4))",
|
|
393
|
+
"language": "tjs",
|
|
394
|
+
"description": "Zero-copy arrays and automatic data marshaling between JS and WASM."
|
|
395
|
+
},
|
|
360
396
|
{
|
|
361
397
|
"title": "React Todo (Comparison)",
|
|
362
398
|
"filename": "react-todo-comparison.md",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
+
}
|