@arcweave/arcscript parses and executes Arcscript embedded in the HTML generated by the Arcweave editor. It can evaluate conditions, update variable state, produce rendered HTML, and rewrite variable or scope references.
npm install @arcweave/arcscriptThe package expects browser DOM APIs, including document and DOMParser. Node.js consumers must provide a compatible DOM implementation.
Arcscript code must be provided as an HTML fragment containing <pre><code> elements.
import { Interpreter } from '@arcweave/arcscript';
const interpreter = new Interpreter({
state: {
health: {
id: 'health',
name: 'health',
type: 'integer',
defaultValue: 100,
},
},
});
const code = [
'<pre><code>health -= 10</code></pre>',
'<pre><code>show(health)</code></pre>',
].join('');
const { changes, output } = interpreter.runScript(code);
console.log(changes);
// { health: 90 }
console.log(output);
// <p>90</p>The state option is a record keyed by variable ID. Each key must match the variable's id property.
const interpreter = new Interpreter({
state: {
playerName: {
id: 'playerName',
name: 'name',
type: 'string',
defaultValue: 'Ada',
},
playerHealth: {
id: 'playerHealth',
name: 'health',
type: 'integer',
defaultValue: 100,
value: 75,
scope: 'player',
},
},
});| Property | Required | Description |
|---|---|---|
id |
Yes | Stable variable ID. It must match the containing record key. |
name |
Yes | Name referenced by Arcscript. |
type |
Yes | string, integer, float, or boolean. |
defaultValue |
Yes | Initial value and the value restored by reset(). |
value |
No | Current value that overrides defaultValue during initialization. |
scope |
No | Scope qualifier. Omitted, undefined, or null means unscoped/global. |
Any string is treated as a named scope. In particular, scope: "global" defines a literal scope named global; it does not define an unscoped variable.
const interpreter = new Interpreter({
state: {
playerHealth: {
id: 'playerHealth',
name: 'health',
type: 'integer',
defaultValue: 100,
scope: 'player',
},
},
});
const { changes } = interpreter.runScript(
'<pre><code>player.health -= 10</code></pre>'
);
console.log(changes);
// { playerHealth: 90 }Each runScript() call creates fresh runtime state. Pass previous changes as the second argument when later runs should continue from those values. The following example uses the interpreter from Quick Start.
const firstRun = interpreter.runScript(
'<pre><code>health -= 10</code></pre>'
);
const secondRun = interpreter.runScript(
'<pre><code>show(health)</code></pre>',
firstRun.changes
);
console.log(secondRun.output);
// <p>90</p>Values supplied as overrides are marked as changed and are included in the returned changes object.
When the input is a condition, the evaluation result is available through result.condition. The following example uses the interpreter from Quick Start.
const { result } = interpreter.runScript(
'<pre><code>health > 0</code></pre>'
);
console.log(result.condition);
// trueThe package exports ParseError, RuntimeError, and FatalError.
import {
FatalError,
ParseError,
RuntimeError,
} from '@arcweave/arcscript';
try {
interpreter.runScript(
'<pre><code>unknownVariable = 1</code></pre>'
);
} catch (error) {
if (error instanceof ParseError) {
console.error('Invalid Arcscript:', error.message);
} else if (error instanceof RuntimeError) {
console.error('Arcscript execution failed:', error.message);
} else if (error instanceof FatalError) {
console.error('Fatal interpreter error:', error.message);
} else {
throw error;
}
}Variable replacements are keyed by variable ID, not by Arcscript variable name.
const code = '<pre><code>player.health -= 10</code></pre>';
const renamedVariable = interpreter.replaceVariables(code, {
playerHealth: 'hitPoints',
});
const renamedScope = interpreter.replaceScope(
renamedVariable,
'player',
'enemy'
);Rewriting operates on Arcscript identifier tokens and does not replace matching text inside string literals.
Creates an interpreter. Calling new Interpreter() is valid and creates an interpreter with an empty variable state.
| Option | Description |
|---|---|
state |
Variable definitions keyed by ID. Required when an options object is supplied. |
elementVisits |
Visit counts used by the visits() function. |
currentElement |
Current element ID used by element-aware functions. |
eventHandler |
Callback for interpreter events, such as resetVisits. |
Executes a script or evaluates a condition.
It returns:
changes: variable values changed by assignments, resets, or supplied overrides.output: rendered HTML produced by the script.result: the visitor result. Conditions expose a booleanconditionproperty.
Parses Arcscript and returns the ANTLR character stream, lexer, token stream, parser, and parse tree. This is a low-level API tied to the generated ANTLR implementation and may change between major versions.
Replaces referenced variable names. The replacement record is keyed by variable ID.
Replaces a scope qualifier for variables known to the interpreter state.
Safely rewrites references whose stored variable names are not valid Arcscript identifiers. Replacements are keyed by variable ID. The method accepts raw Arcscript code and preserves its whitespace, entities, strings, and mentions.
String literals, mention spans, operators, and identifiers are recognized with the generated Arcscript lexer, and potential Arcscript expressions are checked with the generated parser. Accepted references are replaced directly at their original source ranges.
const interpreter = new Interpreter({
state: {
score: {
id: 'score',
name: 'score value',
type: 'integer',
defaultValue: 0,
scope: 'hero',
},
},
});
const result = interpreter.rewriteLegacyVariableReferences(
'hero . score value += 1',
{ score: 'score_value' },
{ scopeNames: ['hero'] }
);
console.log(result.code);
// hero . score_value += 1
console.log(result.blockedVariableIds);
// []scopeNames should contain every board/component scope name, including
duplicates. Variables are reported in blockedVariableIds and left unchanged
when their references could instead be Arcscript syntax, when their name is
duplicated within a scope, when a scoped qualifier is invalid or ambiguous, or
when the requested replacement is not a non-reserved Arcscript identifier.
All accepted replacements are located in the original source before any are
applied, so overlapping names cannot consume each other and replacement text
is never reinterpreted.
This project uses the version of pnpm declared in package.json.
pnpm install
pnpm build
pnpm test
pnpm lintThe build writes compiled files and declarations to dist/.
New GitHub releases are automatically published to npmjs.com.
- Fork the repository.
- Create a feature branch.
- Add or update tests for behavioral changes.
- Run the build and test suite.
- Open a pull request.
This project is licensed under the terms in LICENSE.txt.