TypeScript and JavaScript coverage
Canonical Octonode repository documentation.
TypeScript and JavaScript coverage
This document maps the complete TypeScript Handbook surface to Octonode's executable model. It separates TypeScript's erased type system from JavaScript runtime behavior; adding a canvas node for an erased type would not add runtime capability.
Support levels
| Level | Meaning |
|---|---|
| Native graph | JSON-composable behavior has a dedicated node and can be wired on the canvas. |
| Source function | The original TypeScript is compiled into one code.source-function node and runs with JavaScript semantics inside one process. |
| Compile time | TypeScript checks or erases the construct; it is represented in source/schema, not as a runtime node. |
| Planned sync | Execution is possible in a source function, but editable code↔graph structure needs more IR/compiler work. |
The Handbook explicitly describes type annotations as erased output that does not change runtime behavior. Octonode therefore treats the TypeScript compiler as the authority for types and the native catalog as a vocabulary for runtime data flow.
Handbook coverage
| Handbook area | Octonode coverage |
|---|---|
| The Basics | Type checking and emit run during materialization. JavaScript behavior executes in Node 24. Types are compile-time only. |
| Everyday Types | Primitive, array, object, optional, union, literal, alias, interface, function, and assertion syntax compiles normally. JSON-compatible annotations are projected to workflow input schemas. |
| Narrowing | typeof, truthiness, equality, in, instanceof, predicates, discriminated unions, and control-flow analysis execute inside source functions. Basic comparisons and boolean operations also have native math/logic nodes. |
| More on Functions | Optional/default/rest parameters, callbacks, overload implementation bodies, this, and async functions compile in source functions. Function values and overload signatures do not cross workflow edges. |
| Object Types | Interfaces, property modifiers, tuples, intersections, and generic object types are compile-time. Plain runtime objects cross edges; class instances do not. |
| Type Manipulation | Generics, keyof, type-level typeof, indexed access, conditional, mapped, and template-literal types are compile-time only. |
| Classes | Studio indexes and preserves decorators, generics, heritage, visibility, parameter properties, fields, declare/definite assignment, methods, accessors, index signatures, static blocks, abstract/override/readonly modifiers, class expressions, and valid classes nested in fields, methods, constructors, accessors, functions, static blocks, or deeper classes. Addressable explicit instances, including new Outer.Inner(), and exposed defineService methods become workflows; local and imported stateful/inherited behavior executes in the source-function lane. |
| Modules | The project compiler resolves local ESM and CommonJS imports/exports, selects the runtime dependency closure, and preserves side-effect module initialization. External packages resolve through Node at runtime. Cyclic runtime imports are rejected before materialization. |
| Modules Reference | Module resolution uses one TypeScript Program, the project's tsconfig.json or jsconfig.json, and roots of declared dependency projects; it is a build concern rather than a native node family. |
| Declaration Files | .d.ts authoring and library declarations affect checking only and produce no runtime nodes. |
| Understanding Errors | Parse and compile diagnostics stop materialization before an invalid executable is registered. |
JavaScript runtime coverage
The ECMAScript iteration statements
and other ordinary statements execute unchanged inside code.source-function:
if,switch, conditional expressions, short-circuiting, and runtime narrowing;for,while,do...while,for...in,for...of,for await...of, labels,break, andcontinue;- assignments, mutation, destructuring, spread/rest, optional chaining, and nullish coalescing;
throw,try,catch, andfinally;- synchronous functions, async functions, closures available in the local preamble,
await, and Promise chains; - standard JavaScript objects and built-ins while their final input/output is JSON-safe.
These statements are intentionally one process, not cyclic ordinary workflow edges. The scheduler remains a DAG. The source index exposes nested structured regions for control statements, and revision-safe source actions replace a region only when its identity and kind remain unambiguous.
Array iteration
The native catalog now exposes the callback-based operations from the ECMAScript Array prototype:
| Node | JavaScript operation | Output |
|---|---|---|
data.map | Array.prototype.map | { items } |
data.filter | Array.prototype.filter | { items } |
data.find | first match | { found, value } |
data.find-index | findIndex | { result } |
data.find-last | last match | { found, value } |
data.find-last-index | findLastIndex | { result } |
data.flat-map | flatMap | { items } |
data.for-each | forEach | mutated/passthrough { items } |
data.some | some | boolean { result } |
data.every | every | boolean { result } |
data.reduce | reduce | { result } |
data.reduce-right | reduceRight | { result } |
Callbacks are materialize-time TypeScript/JavaScript source and are synchronous, just
like the standard Array methods. For asynchronous fan-out, use a source function with
map plus Promise.all, or use workflow Promise topology.
Promises
Native Promise topology supports all, allSettled, any, race, rejection,
settled branching, then, catch, and finally, matching the standard
Promise combinators.
Arbitrary Promise construction and async/await execute within a source function.
A live Promise never crosses an edge; the adapter awaits it first.
JSON workflow boundary
Edges and IPC envelopes can losslessly carry null, booleans, strings, finite numbers,
arrays without holes, and plain objects with string keys. The TypeScript runner rejects
lossy output before writing the response envelope:
| Value | Boundary behavior |
|---|---|
top-level undefined return | normalized to null by code.source-function |
nested undefined, function, symbol, or bigint | rejected |
NaN or positive/negative infinity | rejected |
| sparse array or cyclic object | rejected |
Date, Map, Set, typed array, or class instance | rejected; convert explicitly to JSON data |
| Promise | awaited inside the node; only its resolved JSON value crosses |
find miss | { found: false, value: null }, avoiding ambiguous undefined |
Bidirectional sync boundary
There are two source-import lanes:
- The strict semantic grammar lowers supported expressions, native calls, workflow calls, console calls, and Promise topology into editable graph nodes.
- An unsupported function and its selected project dependency closure are preserved and
compiled as one content-addressed
code.source-functionnode. It executes loops and arbitrary JavaScript correctly; supported control statements also appear as nested source regions without becoming ordinary graph nodes.
Studio can create, replace, export, move, and delete complete declarations with revision
checks and immediate re-indexing. It can also navigate class-owned workflows. Octonode can
execute the JSON-observable behavior of self-contained TypeScript functions and stateful local
classes, imported helpers, and module initialization. It does not claim that every statement
inside a source-function node is independently editable on the canvas. Generators are rejected
at the JSON workflow boundary. Static local require() and import() calls are resolved through
the same project closure; dynamic module specifiers are rejected before artifacts are written.
Exposed source-service methods share one routed host, and stale
source-owned nodes and artifacts are removed only after a successful config replacement.
Local and Cloudflare execution
Local runs spawn the generated TypeScript node's compiled CommonJS artifact. Hosted runs use the same package and artifact path inside the configured Cloudflare Sandbox container; the root Docker build copies the monorepo packages into that image. Infinite or otherwise stuck code is terminated by the existing node invocation timeout. The Worker itself orchestrates/authenticates requests and does not evaluate user code in the isolate.
Cloudflare conformance and the authenticated production smoke are tracked by T120.