npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@educspace/eval-editor

v0.4.0

Published

Angular components for authoring educspace exercises: per-kind forms, a markdown editor, and the pure Question↔form mapping behind them.

Readme

@educspace/eval-editor

Angular components for authoring exercises, as packages/element is for answering them.

The same forms serve slate's console and the questions console. The two tools disagree about storage, identity and everything around an exercise — sessions and tags on one side, classes and deadlines on the other — but not about what an exercise is. That part is Question, and this is its editor.

<eds-question-editor #editor [question]="question" kind="code" />
<button (click)="save(editor.current())">Enregistrer</button>

Nothing here talks to a server: a host passes a Question in, reads one back, and keeps its own vocabulary to itself.

What is in it

| | | | --------------------------------------------------------------------------------- | -------------------------------------------------------- | | QuestionEditor | title, prompt and the kind-specific half, assembled | | FreeTextKind, ChoiceKind, OrderedListKind, CodeKind, WebKind, SqlKind | the halves, exported so a host can compose its own | | MarkdownEditor | Write / Split / Preview, as a form control | | renderMarkdown | markdown + $…$ KaTeX + highlighted code, sanitised | | MonacoEditor, MonacoLoader | Monaco as a form control, from a CDN or the app's assets | | toFormValue / toQuestion | the mapping, as pure functions |

That last row is the part worth knowing about. Seven kinds each have their own config and their own way of being subtly wrong — a choice whose "correct" flag follows the wrong index, a code exercise that loses its hidden post on save. That is logic, not markup, so it lives apart from the components in question-form.ts and is tested without a browser.

Wording

The labels are French by default. A library cannot use Angular's i18n attributes usefully — extraction only scans an application's own sources — so the strings are data instead:

{ provide: EDS_EDITOR_LABELS, useValue: myLabels }

slate, which ships English and French, builds its EditorLabels from $localize, so both go through its own i18n pipeline.

Monaco

Loaded from a CDN by default, so a consuming app needs no build configuration — dropping in a component should not mean copying megabytes into someone's assets/. An app that must work offline provides its own source instead:

{ provide: MONACO_SOURCE, useValue: localMonaco('assets/monaco') }

slate does exactly that: it runs a classroom on a local network, sometimes with no internet at all. When Monaco cannot load either way, the editors fall back to plain textareas — authoring has to survive a bad network.

What it deliberately leaves out

  • Identity, mode, policy, tags, sheets. All of it belongs to the host.
  • The kind is fixed while editing: changing it would throw away everything typed so far, so a host that wants another kind creates another question.
  • Attachments. The bytes need a store, which is the host's again. What the library takes is a resolveAttachment function so the prompt preview can show attachments/<name> images when the host can resolve them.

Build

npm install
npm run build     # dist/ — an Angular partial-compilation package
npm test          # the form mapping