Octonode Playbook

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

LevelMeaning
Native graphJSON-composable behavior has a dedicated node and can be wired on the canvas.
Source functionThe original TypeScript is compiled into one code.source-function node and runs with JavaScript semantics inside one process.
Compile timeTypeScript checks or erases the construct; it is represented in source/schema, not as a runtime node.
Planned syncExecution 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 areaOctonode coverage
The BasicsType checking and emit run during materialization. JavaScript behavior executes in Node 24. Types are compile-time only.
Everyday TypesPrimitive, array, object, optional, union, literal, alias, interface, function, and assertion syntax compiles normally. JSON-compatible annotations are projected to workflow input schemas.
Narrowingtypeof, 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 FunctionsOptional/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 TypesInterfaces, property modifiers, tuples, intersections, and generic object types are compile-time. Plain runtime objects cross edges; class instances do not.
Type ManipulationGenerics, keyof, type-level typeof, indexed access, conditional, mapped, and template-literal types are compile-time only.
ClassesStudio 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.
ModulesThe 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 ReferenceModule 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 ErrorsParse 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, and continue;
  • assignments, mutation, destructuring, spread/rest, optional chaining, and nullish coalescing;
  • throw, try, catch, and finally;
  • 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:

NodeJavaScript operationOutput
data.mapArray.prototype.map{ items }
data.filterArray.prototype.filter{ items }
data.findfirst match{ found, value }
data.find-indexfindIndex{ result }
data.find-lastlast match{ found, value }
data.find-last-indexfindLastIndex{ result }
data.flat-mapflatMap{ items }
data.for-eachforEachmutated/passthrough { items }
data.somesomeboolean { result }
data.everyeveryboolean { result }
data.reducereduce{ result }
data.reduce-rightreduceRight{ 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:

ValueBoundary behavior
top-level undefined returnnormalized to null by code.source-function
nested undefined, function, symbol, or bigintrejected
NaN or positive/negative infinityrejected
sparse array or cyclic objectrejected
Date, Map, Set, typed array, or class instancerejected; convert explicitly to JSON data
Promiseawaited 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:

  1. The strict semantic grammar lowers supported expressions, native calls, workflow calls, console calls, and Promise topology into editable graph nodes.
  2. An unsupported function and its selected project dependency closure are preserved and compiled as one content-addressed code.source-function node. 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.

On this page