Skip to content

Proxy Calls ​

How me.whatever(what) works in the TypeScript kernel, this.me 4.2.1: one callable object, a JavaScript Proxy, turns property access into a path and a call into a write or a read.

Concept first: me.whatever(what) (writing and reading paths) · me.explain(path) (why a value has its value). This page maps that onto the source.

Source map ​

All links are pinned to tag v4.2.1 (the commit published to npm as this.me 4.2.1).

FileRoleWhere
proxy.tsBuilds the path from property access; decides member vs pathcreateProxy L256–303 · member check L287–292 · normalizeArgs L32–36
handleCall.tsRoutes a call: root read, seed, root postulate, path writehandleCall L87–156
core-write.tsEvery writepostulate L983–1101 · declareDerivation L1129–1137
core.tsReadsreadPath L289–393
operators.tsDetects operator calls such as ["="]isEvalCall L196–223
derivation.tsFormulas, dependencies, invalidation, explainexplain L140–251 · registerDerivation L577–608 · invalidateFromPaths L824–961
me.tsThe ME class and its membersclass ME L254 · inspect / explain L474–484 · readPath L1548–1554

The example ​

Run against this.me 4.2.1 (npm):

ts
import ME from "this.me";
const me = new ME();

me.colony.pantry.seeds(40);
me.colony.pantry.honey(12);
me.colony["="]("food", "pantry.seeds + pantry.honey");
me("colony.food");          // → 52
me.colony.pantry.seeds(45);
me("colony.food");          // → 57
me.explain("colony.food");  // → below
json
{
  "path": "colony.food",
  "value": 57,
  "expr": "pantry.seeds + pantry.honey",
  "derivation": {
    "expression": "pantry.seeds + pantry.honey",
    "inputs": [
      { "label": "pantry.seeds", "path": "colony.pantry.seeds", "value": 45, "origin": "public", "masked": false, "status": "resolved" },
      { "label": "pantry.honey", "path": "colony.pantry.honey", "value": 12, "origin": "public", "masked": false, "status": "resolved" }
    ]
  },
  "meta": {
    "dependsOn": ["colony.pantry.seeds", "colony.pantry.honey"],
    "k": 1,
    "recomputed": ["colony.food"],
    "changed": ["colony.food"],
    "sourcePath": "colony.pantry.seeds"
  }
}

(lastComputedAt / recomputedAt timestamps omitted.)

1. Property access builds a path ​

me is a function wrapped in a Proxy (L256–303). Its get trap (L283–298) checks, in order:

  1. a symbol → returned from the target;
  2. "!" → the runtime plane, createRuntimeProxy (L216);
  3. prop in self → a member of the kernel instance: methods are returned bound to the caller scope (L287–292);
  4. anything else → a new proxy one segment deeper: [...path, prop] (L296–297).

So me.colony.pantry.seeds is a proxy holding ["colony", "pantry", "seeds"]; nothing is read or written yet.

The member check runs at every depth, not only on the root: every proxy shares the same self. me.colony.explain is the explain method, not the path colony.explain:

ts
typeof me.colony.explain;                      // → "function"
me.colony.explain("colony.food").value;        // → 57

Members are the ME instance API (me.ts L474–919): explain, inspect, execute, exportSnapshot, hydrate, learn, setRecomputeMode, … plus inherited names such as toString. Any other name is a path.

2. A call is routed by handleCall ​

Calling a proxy runs its function body (L261–280) → handleCall:

CallRouteLines
me("a.b"), me("a"), me("_x")read: readPathL89–111
me("ana", "luna")seed identity (who + secret)L113–125
me()root proxyL128–130
me(expression)root postulateL133–137
me.a.b(v)write at a.b, returns a proxy for chainingL141–155

Arguments go through normalizeArgs: none → undefined, one → the value, several → an array. That is why me.a.b() is a write of undefined, not a read.

3. Write: me.colony.pantry.seeds(45) ​

  1. handleCall (non-root) → self.postulate(path, 45) (me.ts L1342).
  2. postulate: operator checks; a plain value is normalized and committed — commitValueMapping → commitMemoryOnly (hash-chained memory) → applyMemoryToIndex.
  3. invalidateFromPaths recomputes dependents: here colony.food (k = 1, sourcePath = "colony.pantry.seeds" above).
  4. handleCall returns a proxy on the same branch (L147–155).

4. Read: me("colony.food") ​

  1. Root call with one string: classifyPathExpression (aggregate strings go to readPathExpression); a dotted path goes to readPath (L97–110).
  2. ME.readPath: stealth check for the caller scope (L1520).
  3. Core.readPath: transforms → selections → lazy refresh (ensureTargetFresh) → filters → secret branch scope → index / pointers.

5. Formula: me.colony["="]("food", "pantry.seeds + pantry.honey") ​

  1. "=" is not a member, so the path is ["colony", "="]; the call passes ["food", "pantry.seeds + pantry.honey"].
  2. isEvalCall recognises the operator inside postulate.
  3. declareDerivation: registerDerivation (inputs colony.pantry.seeds, colony.pantry.honey) → computeDerivation → postulate(colony.food, 52, "=").
  4. The chain continues on colony, the scope, because the leaf was an operator (L148–149).

6. me.explain("colony.food") ​

explain is a member (step 1) → ME.explain → Derivation.explain: the value, expr, derivation.inputs (masked when an input is under a secret the caller can't see) and meta from the last recompute wave.

Rust ​

Rust has no Proxy. Members are methods on Kernel and a path is always an argument, so a path can never shadow a member: kernel.postulate("a.b", v), kernel.read("a.b"), kernel.explain("a.b"). Strings become paths through IntoPath (rust-v0.3.3); postulate is at mod.rs L633–639. See the Rust API.

Tests ​

dsl.contract.test.mjs at v4.2.1:

See also ​

Runtime Surface · Operators · Syntax · API: ME class · me.whatever(what) · me.explain(path)

Human owns meaning. Everything else asks.