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

@curiouslearning/assessment-survey

v1.0.0

Published

typescript implementation of the assessment / survey

Downloads

588

Readme

Assessment, Survey re-implementation from Curious Learning in Typescript

[ ] Building the Project

- First we need to have a Typescript transpiler installed by using the following command:

npm install -g typescript

- The Typescript config is already included in the project, now we need to install the typescript-bundle Typescript bundler tool to be able to use import statements and much more, by using the following command:

npm install -g typescript-bundle

- In order to build the compile/transpile Typescript to Javascript let's use the following command:

tsc

- Now we can move on to bundling the generated Javascript files into one bundle that can be referenced as a script on a page, by using the following command:

tsc-bundle tsconfig.json

[ ] Running the Project

- Currently the preferred way of running the project is by using the live-server command line application that creates a localhost server and hosts the project and enables, more on that here.

npm package outputs

This repository now supports two build targets:

  • Standalone app bundle (for direct hosting):
    • npm run build:standalone
  • Package build (for npm distribution):
    • npm run build:package

The package build emits ESM JS + type declarations into dist/.

Working locally with this package

Use this workflow when developing @curiouslearning/assessment-survey and testing changes in a separate host app without publishing to npm.

Option A: Use npm link (fast iteration)

In this package repo (assessment-survey-js):

npm run build:package
npm link

In your host app repo:

npm link @curiouslearning/assessment-survey

After making changes here, rebuild to refresh dist/:

npm run build:package

When done, unlink in the host app:

npm unlink @curiouslearning/assessment-survey

And optionally remove the global link from this package repo:

npm unlink

Option B: Use local tarball (closest to publish)

In this package repo:

npm run build:package
npm pack

Then install the generated .tgz in your host app:

npm install ../assessment-survey-js/curiouslearning-assessment-survey-0.0.1.tgz

Use this option to validate exactly what files are included in the distributed package.

Web component usage (host integration)

The package exports a custom element registration entry.

Register globally

import '@curiouslearning/assessment-survey/register';

Render component

<assessment-survey-player
	data-key="zulu-lettersounds"
	user-id="123"
	user-source="host-app"
	asset-base-url="/assets/assessment-survey"
	data-base-url="/assets/assessment-survey"
	host-theme="ftm-dim"
	embed-mode="true"
></assessment-survey-player>

embed-mode="true" applies host-friendly defaults (skip-loading-screen=true, skip-start-screen=true, enable-service-worker=false, enable-unity-bridge=false, enable-android-summary=false, enable-parent-post-message=false).

You can still set any of those attributes explicitly when a host needs a different value. Explicit attribute values always override the embed-mode preset.

data-base-url is optional. If omitted, the component uses asset-base-url for data-key JSON loading.

skip-loading-screen remains recommended in host integration mode when the host app preloads and caches the selected language pack before mounting the component.

host-theme="ftm-dim" is an optional embed-only visual variant that replaces the default gradient with a dim transparent background so host content can remain visible behind the assessment UI.

Listen to events

const player = document.querySelector('assessment-survey-player');

player?.addEventListener('loaded', () => {
	console.log('Assessment loaded');
});

player?.addEventListener('completed', (event: Event) => {
	const customEvent = event as CustomEvent;
	console.log('Assessment completed', customEvent.detail);
});

Subscribe with the element PubSub

import { AssessmentSurveyPlayerElement } from '@curiouslearning/assessment-survey';

const player = document.querySelector('assessment-survey-player') as AssessmentSurveyPlayerElement;

player?.subscribe(AssessmentSurveyPlayerElement.ONCOMPLETE, (payload) => {
	console.log('Assessment complete', payload.score);
});

player?.subscribe(AssessmentSurveyPlayerElement.ONCLOSE, () => {
	console.log('Assessment closed');
});

player?.subscribe(AssessmentSurveyPlayerElement.ONREWARDTRIGGER, (payload) => {
	console.log('Trigger host reward flow', payload.score);
});

AssessmentSurveyPlayerElement.ONCOMPLETE and AssessmentSurveyPlayerElement.ONREWARDTRIGGER fire from the assessment completion path through the element's internal @curiouslearning/core PubSub. The exported constants keep the host event names stable: loaded, closed, summary, completed, and reward-trigger.

Load and cache only one selected language

Use a single language/content key at a time (for example: zulu-lettersounds).

  • Resolve selected key in host app:
    • selectedKey = userSelectedLanguageKey ?? defaultLanguageKey
  • Render component with only that key:
    • data-key="<selectedKey>"
  • Preload and cache only this pack in host service worker:
    • /assets/assessment-survey/data/<selectedKey>.json
    • /assets/assessment-survey/audio/<selectedKey>/**
    • shared static assets once (css, img, animation)

Recommended host behavior:

  • Do not precache all language folders.
  • Warm only selected/default language at host startup.
  • On language change, invalidate old key and warm new key.
  • Track readiness marker by key and content version:
    • assessment:<selectedKey>:<contentVersion>:ready

Manual host wrapper mode (instantiate App directly)

You can skip the built-in <assessment-survey-player> and instantiate App directly from your own host web component.

Host TypeScript usage

import { createApp, type AppStartupConfig } from '@curiouslearning/assessment-survey';

const config: AppStartupConfig = {
	dataURL: 'zulu-lettersounds',
	uiRoot: hostElement, // your host component root element
	assetBaseUrl: '/assets/assessment-survey',
	dataBaseUrl: '/assets/assessment-survey',
	waitForWindowLoad: false,
	skipLoadingScreen: true,
	skipStartScreen: true,
	enableServiceWorker: false,
	enableUnityBridge: false,
	enableAndroidSummary: false,
	enableParentPostMessage: false
};

const app = createApp(config);
app.spinUp(config);

Required DOM IDs in host template

If you use manual mode, your host template must include the expected IDs used by UI logic:

  • landWrap, gameWrap, endWrap
  • starWrapper, qWrap, feedbackWrap, aWrap
  • answerButton1 ... answerButton6
  • pbutton, chestImage
  • loadingScreen, progressBar
  • Dev mode controls:
    • devModeModalToggleButtonContainer
    • devModeModalToggleButton
    • devModeSettingsModal
    • devModeBucketGenSelect
    • devModeCorrectLabelShownCheckbox
    • devModeBucketInfoShownCheckbox
    • devModeBucketInfoContainer
    • devModeBucketControlsShownCheckbox
    • devModeAnimationSpeedMultiplierRange
    • devModeAnimationSpeedMultiplierValue

What is overridable from host today

Overridable via AppStartupConfig:

  • Data/config: dataURL, userId, userSource, requiredScore, nextAssessment, endpoint, organization
  • Asset/runtime: assetBaseUrl, dataBaseUrl, waitForWindowLoad, skipLoadingScreen, skipStartScreen
  • Integrations: enableServiceWorker, enableUnityBridge, enableAndroidSummary, enableParentPostMessage
  • Host callbacks via hostIntegrationAdapters:
    • onLoaded, onClose, onSummaryData, onComplete, onRewardTrigger, onAssessmentCompleted

Not fully overrideable yet:

  • Multiple concurrent player instances (current UI controller is singleton-oriented)
  • Deep UI structure changes without keeping required IDs
  • Full replacement of internal game flow without forking game classes