Developer mode

Pick a language, then move through 10 levels. Indentation, brackets, quotes and backticks stay in the snippet. Code is never executed.

javascript · 10 levels

Level 1

Hello const

const name = "Ada";
const wpm = 42;
const ready = true;

console.log(name);
console.log(wpm);

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 2

Add function

function add(a, b) {
  const total = a + b;
  return total;
}

const score = add(40, 8);
console.log(score);
console.log("ok");

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 3

Object literal

const user = {
  id: 1,
  name: "Ada",
  wpm: 48,
  ready: true
};

function label(item) {
  return item.name + ":" + item.wpm;
}

console.log(label(user));

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 4

If branch

function start(count, ready) {
  if (!ready) {
    console.log("wait");
    return false;
  }
  if (count > 0) {
    console.log("go");
    return true;
  }
  console.log("empty");
  return false;
}

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 5

Array map

const items = [
  { id: 1, ok: true, wpm: 48 },
  { id: 2, ok: false, wpm: 12 },
  { id: 3, ok: true, wpm: 71 }
];

const ids = items
  .filter((item) => item.ok)
  .map((item) => item.id);

const total = items
  .filter((item) => item.ok)
  .reduce((sum, item) => sum + item.wpm, 0);

console.log(ids);
console.log(total);

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 6

Template string

const user = {
  name: "Ada",
  email: "ada@keyfun.space",
  wpm: 64,
  layout: "qwerty"
};

function card(item) {
  const tag = item.wpm >= 60 ? "fast" : "warm";
  return `${item.name} <${item.email}> ${tag}`;
}

function line(item) {
  return `${card(item)} [${item.layout}]`;
}

console.log(card(user));
console.log(line(user));
console.log(user.wpm);

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}

function step2(value) {
  const next = value + 2;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 7

Debounce

function debounce(fn, wait) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn(...args);
    }, wait);
  };
}

const save = debounce((value) => {
  console.log("save", value);
}, 250);

function persist(draft, finalValue) {
  save(draft);
  save(finalValue);
}

persist("draft", "final");
console.log("queued");

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}

function step2(value) {
  const next = value + 2;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 8

Fetch json

async function loadUser(id) {
  const res = await fetch("/api/users/" + id);
  if (!res.ok) {
    throw new Error("fail:" + res.status);
  }
  const data = await res.json();
  return {
    id: data.id,
    name: data.name,
    wpm: data.wpm ?? 0,
    layout: data.layout ?? "qwerty"
  };
}

async function boot() {
  const user = await loadUser("u_1");
  console.log(user.name, user.wpm);
  console.log(user.layout);
}

boot();

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}

function step2(value) {
  const next = value + 2;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 9

Regex replace

function render(src, ctx) {
  return src.replace(/\{\{([a-z_]+)\}\}/g, (_, name) => {
    const value = ctx[name];
    return value == null ? "" : String(value);
  });
}

const template = "Hello {{name}}, WPM={{wpm}}";
const html = render(template, {
  name: "Ada",
  wpm: 72,
  layout: "azerty"
});

function countTokens(text) {
  const matches = text.match(/\{\{[a-z_]+\}\}/g);
  return matches ? matches.length : 0;
}

function preview(text) {
  return text.slice(0, 24);
}

console.log(html);
console.log(countTokens(template));
console.log(preview(html));

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}

function step2(value) {
  const next = value + 2;
  if (next > 0) {
    return next;
  }
  return 0;
}
Level 10

Nested filter

function collectIds(groups) {
  return groups
    .filter((group) => group.active)
    .flatMap((group) => group.items)
    .filter((item) => item.ok && item.wpm >= 40)
    .map((item) => item.id);
}

const nested = [
  { active: true, items: [{ id: "a", ok: true, wpm: 55 }] },
  { active: false, items: [{ id: "b", ok: true, wpm: 90 }] },
  { active: true, items: [{ id: "c", ok: false, wpm: 70 }] }
];

function summary(ids) {
  return {
    count: ids.length,
    first: ids[0] ?? null,
    last: ids[ids.length - 1] ?? null
  };
}

const ids = collectIds(nested);
console.log(summary(ids));
console.log(ids.join(","));

function step1(value) {
  const next = value + 1;
  if (next > 0) {
    return next;
  }
  return 0;
}

function step2(value) {
  const next = value + 2;
  if (next > 0) {
    return next;
  }
  return 0;
}

function step3(value) {
  const next = value + 3;
  if (next > 0) {
    return next;
  }
  return 0;
}

In the arena, switch levels without leaving javascript.