Arcane OS Docs Development only

Reference

Questionnaire module

Reusable in-memory policy for deciding when an unshown questionnaire prompt is due.

  • Reference

arcane/modules/Questionnaire.js provides a synchronous, in-memory policy for deciding when an application may present a one-time questionnaire prompt. It does not initialize timestamps, persist state, create or order modals, or open a questionnaire URL. Those responsibilities remain with the consuming application.

Loading and exports

Import the class and its default delay from the shared module:

import {
    DEFAULT_QUESTIONNAIRE_NOTIFICATION_TIME_MS,
    Questionnaire
} from './arcane/modules/Questionnaire.js';

The module exports:

Export Description
DEFAULT_QUESTIONNAIRE_NOTIFICATION_TIME_MS Exactly 604,800,000 elapsed milliseconds, or seven 24-hour periods
Questionnaire An independent evaluator whose notification delay exists only for the lifetime of that instance

There is no default export.

Constructing Questionnaire has no side effects. It does not start a timer, read global state, load a user, or dispatch an event.

Eligibility rule

checkQuestionnaireShown(firstBootUp, questionnaireShown, now) returns true only when every condition below is satisfied:

  1. questionnaireShown is exactly false.
  2. firstBootUp is a positive safe-integer timestamp in milliseconds.
  3. now is finite and is not earlier than firstBootUp.
  4. now - firstBootUp is greater than or equal to the configured notification delay.

The default boundary is exact elapsed time rather than calendar-day arithmetic:

now - firstBootUp <  604,800,000    returns false
now - firstBootUp >= 604,800,000    returns true

A firstBootUp value of 0, a missing or malformed timestamp, a timestamp in the future, or any shown-state value other than the boolean false returns false. Invalid eligibility state fails closed and does not throw.

Despite its name, checkQuestionnaireShown() answers whether an unshown prompt is due. It does not report whether a questionnaire was completed.

API

new Questionnaire()

Creates an evaluator with the default seven-day notification delay. Each instance owns its own delay, so changing one instance does not affect another.

setNotificationTime(notificationTime)

Replaces the instance's delay with a positive finite number of milliseconds, including a positive fractional value. The change is in memory only and is not serialized or shared with another instance. The method returns undefined.

The method throws a RangeError with notificationTime must be a positive finite number when the supplied value is zero, negative, NaN, infinite, or not a number.

checkQuestionnaireShown(firstBootUp, questionnaireShown, now = Date.now())

Synchronously returns a boolean using the eligibility rule above. Supplying now makes the result deterministic for tests. Omitting it uses Date.now() at the time of the call.

Application-owned integration

The application should initialize and persist its timestamp separately, invoke the evaluator from an application lifecycle event or page load, and present its own user interface only when the evaluator returns true:

const questionnaire=new Questionnaire();

if(user.firstBootUp===0){
    await user.updateExplicit({firstBootUp:Date.now()});
}else if(questionnaire.checkQuestionnaireShown(
    user.firstBootUp,
    user.questionnaireShown
)){
    const opened=await applicationModal.open();

    if(opened){
        await user.updateExplicit({questionnaireShown:true});
    }
}

The example is orchestration, not behavior supplied by Questionnaire. A consumer may use different field names or persistence as long as it maps them to the same timestamp and boolean contract.

Operational boundaries

Concern Module behavior
Synchronous Both public methods complete synchronously
Asynchronous No promises, background tasks, polling, or timers
Persistent No; delay and evaluation state remain in memory
Destructive No
Networked No; the module never loads or validates a form URL
User interface No; modal creation, readiness, ordering, content, and focus remain application-owned

An application must own any asynchronous modal task and observe its failures. It should mark a prompt as shown only after presentation succeeds if it needs a failed presentation to remain eligible on a later load. Showing a prompt is not proof that a third-party questionnaire was opened, submitted, or completed.

Repository and reviewed source access