Example: Todo list

A persistent CRUD list — add tasks, double-click to toggle done, delete with a confirmation, and JSON persistence via sw.fs. Built on a Treeview and an Entry.

Run it:

scriptweaver internal/scriptweaver/testdata/todo.js

Add a task, double-click to mark it ✓, then relaunch — your list is restored.

One source of truth

The todos array is the model; render() rebuilds the tree from it on every change:

function render() {
  const kids = tv.children('');
  if (kids.length) tv.delete(...kids);
  rowToIndex = {};
  todos.forEach((t, i) => {
    const id = tv.insert('', 'end', { text: t.text });
    tv.set(id, 'done', t.done ? '✓' : '');
    rowToIndex[id] = i;
  });
}

Add and delete

function addCurrent() {
  const t = entry.value.trim();
  if (!t) return;
  todos.push({ text: t, done: false });
  entry.clear();
  save();
  render();
}
function deleteSelected() {
  const i = selectedIndex();
  if (i >= 0 && sw.dialog.confirm(`Delete "${todos[i].text}"?`)) {
    todos.splice(i, 1);
    save();
    render();
  }
}

Persistence

save() writes JSON; a matching loader reads it at startup:

function save() {
  sw.fs.mkdir(dirOf(dataFile));
  sw.fs.writeFile(dataFile, JSON.stringify(todos, null, 2));
}

The data file is $SW_TODO_FILE, or <config>/scriptweaver/todos.json.

Full source: internal/scriptweaver/testdata/todo.js.

See also