eyeling 1.24.9 → 1.24.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/HANDBOOK.md CHANGED
@@ -1818,7 +1818,7 @@ Some N3 workflows treat IRIs as pointers to more knowledge. Eyeling supports thi
1818
1818
  - in practice, any non-http IRI is treated as a local path for convenience.
1819
1819
 
1820
1820
  - In **browser/worker**, dereferencing uses synchronous XHR (HTTP(S) only), subject to CORS.
1821
- - Many browsers restrict synchronous XHR on the main thread; use a worker (as in `demo.html`) to avoid UI blocking.
1821
+ - Many browsers restrict synchronous XHR on the main thread; use a worker (as in `playground.html`) to avoid UI blocking.
1822
1822
 
1823
1823
  ### 12.2 Caching
1824
1824
 
@@ -2004,7 +2004,7 @@ For browser apps, prefer running Eyeling in a **Web Worker** and importing `eyel
2004
2004
  `lib/entry.js` exports:
2005
2005
 
2006
2006
  - public APIs: `reasonStream`, `reasonRdfJs`, `rdfjs`, `main`, `version`
2007
- - plus a curated set of internals used by the demo (`lex`, `Parser`, `forwardChain`, etc.)
2007
+ - plus a curated set of internals used by the playground (`lex`, `Parser`, `forwardChain`, etc.)
2008
2008
 
2009
2009
  `rdfjs` is a small built-in RDF/JS `DataFactory`, so browser / worker code can construct quads without pulling in another package first.
2010
2010
 
package/README.md CHANGED
@@ -16,5 +16,5 @@ echo '@prefix : <http://example.org/> .
16
16
  ## Read more
17
17
 
18
18
  - [Handbook](https://eyereasoner.github.io/eyeling/HANDBOOK)
19
- - [Playground](https://eyereasoner.github.io/eyeling/demo)
19
+ - [Playground](https://eyereasoner.github.io/eyeling/playground)
20
20
  - [Conformance report](https://codeberg.org/phochste/notation3tests/src/branch/main/reports/report.md)
@@ -8898,10 +8898,10 @@ function main() {
8898
8898
  }
8899
8899
 
8900
8900
  // ---------------------------------------------------------------------------
8901
- // Internals (exposed for demo.html)
8901
+ // Internals (exposed for playground.html)
8902
8902
  // ---------------------------------------------------------------------------
8903
8903
  // The original monolithic eyeling.js exposed many internal functions and flags
8904
- // as globals. demo.html (web worker) still relies on a subset of these.
8904
+ // as globals. playground.html (web worker) still relies on a subset of these.
8905
8905
 
8906
8906
  function getEnforceHttpsEnabled() {
8907
8907
  return deref.getEnforceHttpsEnabled();
@@ -8946,12 +8946,12 @@ module.exports = {
8946
8946
  N3SyntaxError,
8947
8947
  Parser,
8948
8948
  lex,
8949
- // demo internals
8949
+ // playground internals
8950
8950
  forwardChain,
8951
8951
  materializeRdfLists,
8952
8952
  isGroundTriple,
8953
8953
  printExplanation,
8954
- // used by demo worker to stringify derived triples with prefixes
8954
+ // used by playground worker to stringify derived triples with prefixes
8955
8955
  tripleToN3,
8956
8956
  tripleToRdfCompatible,
8957
8957
  // pretty log:query output (when proof comments are disabled)
@@ -8985,7 +8985,7 @@ module.exports = {
8985
8985
  'use strict';
8986
8986
 
8987
8987
  // Entry point for the bundled eyeling.js.
8988
- // We intentionally re-export a small set of internals so demo.html (worker)
8988
+ // We intentionally re-export a small set of internals so playground.html (worker)
8989
8989
  // can call into the reasoner like the original monolithic build did.
8990
8990
 
8991
8991
  const engine = require('./engine');
@@ -8999,7 +8999,7 @@ module.exports = {
8999
8999
  main: engine.main,
9000
9000
  version: engine.version,
9001
9001
 
9002
- // internals for demo.html
9002
+ // internals for playground.html
9003
9003
  lex: engine.lex,
9004
9004
  Parser: engine.Parser,
9005
9005
  forwardChain: engine.forwardChain,
@@ -12283,7 +12283,7 @@ module.exports = {
12283
12283
  * Eyeling Reasoner — printing
12284
12284
  *
12285
12285
  * Pretty-printing / serialization helpers for terms, triples, and formulas.
12286
- * Used by the CLI, demo, and explanations.
12286
+ * Used by the CLI, playground, and explanations.
12287
12287
  */
12288
12288
 
12289
12289
  'use strict';
@@ -13813,7 +13813,7 @@ module.exports = {
13813
13813
  'use strict';
13814
13814
 
13815
13815
  // Small module for debug/trace printing (log:trace) and its run-level state.
13816
- // Kept separate from engine.js so browser demo + CLI can share behavior.
13816
+ // Kept separate from engine.js so browser playground + CLI can share behavior.
13817
13817
 
13818
13818
  let tracePrefixes = null;
13819
13819
 
@@ -13899,9 +13899,9 @@ module.exports = {
13899
13899
  try { if (__outerModule && __outerModule.exports) __outerModule.exports = __api; } catch (ignoredError) {}
13900
13900
  try { if (__outerSelf) __outerSelf.eyeling = __api; } catch (ignoredError) {}
13901
13901
 
13902
- // ---- demo.html compatibility ----
13902
+ // ---- playground.html compatibility ----
13903
13903
  // The original monolithic eyeling.js exposed internal functions/flags as globals.
13904
- // demo.html still uses these via importScripts(...) inside a web worker.
13904
+ // playground.html still uses these via importScripts(...) inside a web worker.
13905
13905
  try {
13906
13906
  if (__outerSelf && __entry) {
13907
13907
  if (typeof __entry.lex === "function") __outerSelf.lex = __entry.lex;
@@ -8,5 +8,5 @@
8
8
 
9
9
 
10
10
  # Markdown rendering via log:outputString.
11
- :__md_output :text "# annotation\n\n## Source files\n\n- [N3 rules](../annotation.n3)\n- [Input TriG](../input/annotation.trig)\n\n" .
11
+ :__md_output :text "# annotation\n\n## Source files\n\n- [N3 rules](../annotation.n3)\n- [Input TriG](../input/annotation.trig)\n\nRDF 1.2 annotation evidence is loaded from the TriG sidecar and represented as ordinary facts.\n\n## Answer\nYES — the annotated statement says `:a :name \"Alice\"` and gives that statement the identifier `:t`.\n\n## Reason Why\nThe input evidence contains the statement that Alice has the name \"Alice\" and records metadata for the named statement `:t`. In RDF compatibility mode, the named graph form is represented with `log:nameOf`, so `:t` names the statement while `:statedBy` and `:recorded` keep its provenance metadata.\n\n## Check\nC1 OK - the statement `:a :name \"Alice\"` is present\nC2 OK - `:t` names the annotated statement\nC3 OK - the statement is attributed to `:bob`\nC4 OK - the statement is recorded as `2021-07-07`\nC5 OK - the RDF/TriG input sidecar is linked as source evidence\n" .
12
12
  { :__md_output :text ?text } log:query { :__md_output log:outputString ?text } .
@@ -208,4 +208,4 @@ Easy extensions:
208
208
  - Connect this to a small “math knowledge base” of reusable lemmas
209
209
  - Use the same pattern for other theorems: “if conditions, then property”
210
210
 
211
- [1]: https://eyereasoner.github.io/eyeling/demo?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/faltings-genus2-finiteness.n3 'Playground'
211
+ [1]: https://eyereasoner.github.io/eyeling/playground?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/faltings-genus2-finiteness.n3 'Playground'
@@ -368,4 +368,4 @@ That is exactly the kind of statement people care about in high-trust software.
368
368
 
369
369
  And the neat part is that the statement is not only written in prose—it is represented as data and rules that a reasoner can check.
370
370
 
371
- [1]: https://eyereasoner.github.io/eyeling/demo?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/high-trust-rdf-bloom-envelope.n3 'Playground'
371
+ [1]: https://eyereasoner.github.io/eyeling/playground?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/high-trust-rdf-bloom-envelope.n3 'Playground'
@@ -244,7 +244,7 @@ This file is a compact demo of:
244
244
  - N3 reasoning as the **transparent logic** connecting them
245
245
  - A ranked report that’s **deterministic** and **explainable**
246
246
 
247
- [1]: https://eyereasoner.github.io/eyeling/demo?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/odrl-dpv-risk-ranked.n3 'Playground'
247
+ [1]: https://eyereasoner.github.io/eyeling/playground?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/odrl-dpv-risk-ranked.n3 'Playground'
248
248
  [2]: https://www.w3.org/TR/odrl-vocab/ 'ODRL Vocabulary & Expression 2.2'
249
249
  [3]: https://dev.dpvcg.org/dpv/modules/risk 'Risk and Impact Assessment'
250
250
  [4]: https://w3c.github.io/N3/spec/ 'Notation3 Language'
@@ -218,4 +218,4 @@ Mapping two models is about **translating meaning across vocabularies**.
218
218
  - You **derive FOAF triples**
219
219
  - The result is data that can be consumed as if it were FOAF, without rewriting your original dataset
220
220
 
221
- [1]: https://eyereasoner.github.io/eyeling/demo?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/schema-foaf-mapping.n3 'Playground'
221
+ [1]: https://eyereasoner.github.io/eyeling/playground?url=https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/examples/schema-foaf-mapping.n3 'Playground'
@@ -5,3 +5,17 @@
5
5
  - [N3 rules](../annotation.n3)
6
6
  - [Input TriG](../input/annotation.trig)
7
7
 
8
+ RDF 1.2 annotation evidence is loaded from the TriG sidecar and represented as ordinary facts.
9
+
10
+ ## Answer
11
+ YES — the annotated statement says `:a :name "Alice"` and gives that statement the identifier `:t`.
12
+
13
+ ## Reason Why
14
+ The input evidence contains the statement that Alice has the name "Alice" and records metadata for the named statement `:t`. In RDF compatibility mode, the named graph form is represented with `log:nameOf`, so `:t` names the statement while `:statedBy` and `:recorded` keep its provenance metadata.
15
+
16
+ ## Check
17
+ C1 OK - the statement `:a :name "Alice"` is present
18
+ C2 OK - `:t` names the annotated statement
19
+ C3 OK - the statement is attributed to `:bob`
20
+ C4 OK - the statement is recorded as `2021-07-07`
21
+ C5 OK - the RDF/TriG input sidecar is linked as source evidence
package/eyeling.js CHANGED
@@ -8898,10 +8898,10 @@ function main() {
8898
8898
  }
8899
8899
 
8900
8900
  // ---------------------------------------------------------------------------
8901
- // Internals (exposed for demo.html)
8901
+ // Internals (exposed for playground.html)
8902
8902
  // ---------------------------------------------------------------------------
8903
8903
  // The original monolithic eyeling.js exposed many internal functions and flags
8904
- // as globals. demo.html (web worker) still relies on a subset of these.
8904
+ // as globals. playground.html (web worker) still relies on a subset of these.
8905
8905
 
8906
8906
  function getEnforceHttpsEnabled() {
8907
8907
  return deref.getEnforceHttpsEnabled();
@@ -8946,12 +8946,12 @@ module.exports = {
8946
8946
  N3SyntaxError,
8947
8947
  Parser,
8948
8948
  lex,
8949
- // demo internals
8949
+ // playground internals
8950
8950
  forwardChain,
8951
8951
  materializeRdfLists,
8952
8952
  isGroundTriple,
8953
8953
  printExplanation,
8954
- // used by demo worker to stringify derived triples with prefixes
8954
+ // used by playground worker to stringify derived triples with prefixes
8955
8955
  tripleToN3,
8956
8956
  tripleToRdfCompatible,
8957
8957
  // pretty log:query output (when proof comments are disabled)
@@ -8985,7 +8985,7 @@ module.exports = {
8985
8985
  'use strict';
8986
8986
 
8987
8987
  // Entry point for the bundled eyeling.js.
8988
- // We intentionally re-export a small set of internals so demo.html (worker)
8988
+ // We intentionally re-export a small set of internals so playground.html (worker)
8989
8989
  // can call into the reasoner like the original monolithic build did.
8990
8990
 
8991
8991
  const engine = require('./engine');
@@ -8999,7 +8999,7 @@ module.exports = {
8999
8999
  main: engine.main,
9000
9000
  version: engine.version,
9001
9001
 
9002
- // internals for demo.html
9002
+ // internals for playground.html
9003
9003
  lex: engine.lex,
9004
9004
  Parser: engine.Parser,
9005
9005
  forwardChain: engine.forwardChain,
@@ -12283,7 +12283,7 @@ module.exports = {
12283
12283
  * Eyeling Reasoner — printing
12284
12284
  *
12285
12285
  * Pretty-printing / serialization helpers for terms, triples, and formulas.
12286
- * Used by the CLI, demo, and explanations.
12286
+ * Used by the CLI, playground, and explanations.
12287
12287
  */
12288
12288
 
12289
12289
  'use strict';
@@ -13813,7 +13813,7 @@ module.exports = {
13813
13813
  'use strict';
13814
13814
 
13815
13815
  // Small module for debug/trace printing (log:trace) and its run-level state.
13816
- // Kept separate from engine.js so browser demo + CLI can share behavior.
13816
+ // Kept separate from engine.js so browser playground + CLI can share behavior.
13817
13817
 
13818
13818
  let tracePrefixes = null;
13819
13819
 
@@ -13899,9 +13899,9 @@ module.exports = {
13899
13899
  try { if (__outerModule && __outerModule.exports) __outerModule.exports = __api; } catch (ignoredError) {}
13900
13900
  try { if (__outerSelf) __outerSelf.eyeling = __api; } catch (ignoredError) {}
13901
13901
 
13902
- // ---- demo.html compatibility ----
13902
+ // ---- playground.html compatibility ----
13903
13903
  // The original monolithic eyeling.js exposed internal functions/flags as globals.
13904
- // demo.html still uses these via importScripts(...) inside a web worker.
13904
+ // playground.html still uses these via importScripts(...) inside a web worker.
13905
13905
  try {
13906
13906
  if (__outerSelf && __entry) {
13907
13907
  if (typeof __entry.lex === "function") __outerSelf.lex = __entry.lex;
package/lib/engine.js CHANGED
@@ -3580,10 +3580,10 @@ function main() {
3580
3580
  }
3581
3581
 
3582
3582
  // ---------------------------------------------------------------------------
3583
- // Internals (exposed for demo.html)
3583
+ // Internals (exposed for playground.html)
3584
3584
  // ---------------------------------------------------------------------------
3585
3585
  // The original monolithic eyeling.js exposed many internal functions and flags
3586
- // as globals. demo.html (web worker) still relies on a subset of these.
3586
+ // as globals. playground.html (web worker) still relies on a subset of these.
3587
3587
 
3588
3588
  function getEnforceHttpsEnabled() {
3589
3589
  return deref.getEnforceHttpsEnabled();
@@ -3628,12 +3628,12 @@ module.exports = {
3628
3628
  N3SyntaxError,
3629
3629
  Parser,
3630
3630
  lex,
3631
- // demo internals
3631
+ // playground internals
3632
3632
  forwardChain,
3633
3633
  materializeRdfLists,
3634
3634
  isGroundTriple,
3635
3635
  printExplanation,
3636
- // used by demo worker to stringify derived triples with prefixes
3636
+ // used by playground worker to stringify derived triples with prefixes
3637
3637
  tripleToN3,
3638
3638
  tripleToRdfCompatible,
3639
3639
  // pretty log:query output (when proof comments are disabled)
package/lib/entry.js CHANGED
@@ -8,7 +8,7 @@
8
8
  'use strict';
9
9
 
10
10
  // Entry point for the bundled eyeling.js.
11
- // We intentionally re-export a small set of internals so demo.html (worker)
11
+ // We intentionally re-export a small set of internals so playground.html (worker)
12
12
  // can call into the reasoner like the original monolithic build did.
13
13
 
14
14
  const engine = require('./engine');
@@ -22,7 +22,7 @@ module.exports = {
22
22
  main: engine.main,
23
23
  version: engine.version,
24
24
 
25
- // internals for demo.html
25
+ // internals for playground.html
26
26
  lex: engine.lex,
27
27
  Parser: engine.Parser,
28
28
  forwardChain: engine.forwardChain,
package/lib/printing.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Eyeling Reasoner — printing
3
3
  *
4
4
  * Pretty-printing / serialization helpers for terms, triples, and formulas.
5
- * Used by the CLI, demo, and explanations.
5
+ * Used by the CLI, playground, and explanations.
6
6
  */
7
7
 
8
8
  'use strict';
package/lib/trace.js CHANGED
@@ -7,7 +7,7 @@
7
7
  'use strict';
8
8
 
9
9
  // Small module for debug/trace printing (log:trace) and its run-level state.
10
- // Kept separate from engine.js so browser demo + CLI can share behavior.
10
+ // Kept separate from engine.js so browser playground + CLI can share behavior.
11
11
 
12
12
  let tracePrefixes = null;
13
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.24.9",
3
+ "version": "1.24.10",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
package/test/api.test.js CHANGED
@@ -6,7 +6,7 @@ const path = require('node:path');
6
6
  const { spawnSync } = require('node:child_process');
7
7
  const ROOT = path.resolve(__dirname, '..');
8
8
  // Direct eyeling.js bundle API (in-process) for testing reasonStream/onDerived.
9
- // This is the API surface used by demo.html (browser/worker).
9
+ // This is the API surface used by playground.html (browser/worker).
10
10
  const { reasonStream } = require('../eyeling.js');
11
11
  const { reason, reasonRdfJs, rdfjs } = require('../index.js');
12
12
 
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- // Smoke-test the browser playground (demo.html).
3
+ // Smoke-test the browser playground (playground.html).
4
4
  //
5
- // Goal: ensure demo.html loads without runtime exceptions and that the default
5
+ // Goal: ensure playground.html loads without runtime exceptions and that the default
6
6
  // Socrates program can be executed to completion ("Done") with non-empty output.
7
7
  //
8
8
  // This test is dependency-free: it drives Chromium directly via the Chrome
@@ -56,18 +56,23 @@ function startStaticServer(rootDir) {
56
56
  return;
57
57
  }
58
58
 
59
- if (pathname === '/' || pathname === '') pathname = '/demo.html';
59
+ if (pathname === '/' || pathname === '') pathname = '/playground.html';
60
60
  // Prevent directory traversal.
61
- const fsPath = path.resolve(rootDir, '.' + pathname);
61
+ let fsPath = path.resolve(rootDir, '.' + pathname);
62
62
  if (!fsPath.startsWith(rootDir)) {
63
63
  res.writeHead(403);
64
64
  res.end('Forbidden');
65
65
  return;
66
66
  }
67
67
 
68
+ // Match GitHub Pages' convenient extensionless HTML URLs for local smoke tests.
69
+ if (!fs.existsSync(fsPath) && !path.extname(fsPath) && fs.existsSync(`${fsPath}.html`)) {
70
+ fsPath = `${fsPath}.html`;
71
+ }
72
+
68
73
  const st = fs.statSync(fsPath);
69
74
  if (st.isDirectory()) {
70
- res.writeHead(301, { Location: pathname.replace(/\/$/, '') + '/demo.html' });
75
+ res.writeHead(301, { Location: pathname.replace(/\/$/, '') + '/playground' });
71
76
  res.end();
72
77
  return;
73
78
  }
@@ -120,7 +125,7 @@ function findChromium() {
120
125
  }
121
126
 
122
127
  // Minimal CodeMirror stub for the playground.
123
- // The real demo loads CodeMirror from a CDN. In CI/offline tests we intercept
128
+ // The real playground loads CodeMirror from a CDN. In CI/offline tests we intercept
124
129
  // those script requests and provide this stub to prevent runtime failures.
125
130
  const CODEMIRROR_STUB = String.raw`(function(){
126
131
  if (window.CodeMirror) return;
@@ -244,7 +249,7 @@ const CODEMIRROR_STUB = String.raw`(function(){
244
249
  getValue: function(){ return textarea.value || ''; },
245
250
  setValue: function(v){ textarea.value = String(v == null ? '' : v); render(); emit('change', api, { origin: 'setValue' }); },
246
251
 
247
- // Methods used by demo.html's streaming appender
252
+ // Methods used by playground.html's streaming appender
248
253
  getScrollerElement: function(){ return obj.scroll; },
249
254
  lastLine: function(){ const ls = getLines(); return Math.max(0, ls.length - 1); },
250
255
  getLine: function(n){ const ls = getLines(); return ls[n] == null ? '' : ls[n]; },
@@ -417,8 +422,10 @@ async function main() {
417
422
  try {
418
423
  const started = await startStaticServer(ROOT);
419
424
  server = started.server;
420
- const demoUrl = `${started.baseUrl}/demo.html`;
421
- info(`Static server: ${demoUrl}`);
425
+ const playgroundUrl = `${started.baseUrl}/playground.html`;
426
+ const cleanPlaygroundUrl = `${started.baseUrl}/playground`;
427
+ const legacyDemoUrl = `${started.baseUrl}/demo?url=https://example.org/example.n3#state`;
428
+ info(`Static server: ${playgroundUrl}`);
422
429
 
423
430
  const chromeArgs = [
424
431
  '--headless=new',
@@ -510,7 +517,7 @@ async function main() {
510
517
  { ct: 'text/css', body: '/* stub */\n' },
511
518
  ],
512
519
 
513
- // GitHub raw references used by demo.html for the "latest version" display.
520
+ // GitHub raw references used by playground.html for the "latest version" display.
514
521
  [
515
522
  'https://raw.githubusercontent.com/eyereasoner/eyeling/refs/heads/main/package.json',
516
523
  { ct: 'application/json', body: localPkg },
@@ -529,6 +536,29 @@ async function main() {
529
536
  ],
530
537
  ]);
531
538
 
539
+ async function getText(url) {
540
+ return new Promise((resolve, reject) => {
541
+ http
542
+ .get(url, (res) => {
543
+ let body = '';
544
+ res.setEncoding('utf8');
545
+ res.on('data', (chunk) => {
546
+ body += chunk;
547
+ });
548
+ res.on('end', () => resolve({ statusCode: res.statusCode, body }));
549
+ })
550
+ .on('error', reject);
551
+ });
552
+ }
553
+
554
+ const cleanRes = await getText(cleanPlaygroundUrl);
555
+ assert.equal(cleanRes.statusCode, 200, 'clean /playground URL should serve the playground');
556
+ assert.match(cleanRes.body, /Eyeling N3 Playground/, 'clean /playground URL should load the playground');
557
+
558
+ const legacyRes = await getText(legacyDemoUrl);
559
+ assert.equal(legacyRes.statusCode, 200, 'legacy /demo URL should serve redirect page');
560
+ assert.match(legacyRes.body, /playground/, 'legacy /demo URL should point to the playground');
561
+
532
562
  await cdp.send(
533
563
  'Fetch.enable',
534
564
  {
@@ -575,8 +605,8 @@ async function main() {
575
605
  });
576
606
 
577
607
  const loadFired = cdp.once('Page.loadEventFired', sessionId, 30000);
578
- const nav = await cdp.send('Page.navigate', { url: demoUrl }, sessionId);
579
- assert.ok(!nav.errorText, `demo.html navigation failed: ${nav.errorText}`);
608
+ const nav = await cdp.send('Page.navigate', { url: playgroundUrl }, sessionId);
609
+ assert.ok(!nav.errorText, `playground.html navigation failed: ${nav.errorText}`);
580
610
  await loadFired;
581
611
 
582
612
  async function evalInPage(expression) {
@@ -594,7 +624,7 @@ async function main() {
594
624
 
595
625
  function failFastOnExceptions() {
596
626
  if (exceptions.length) {
597
- throw new Error(`Uncaught exception in demo.html: ${JSON.stringify(exceptions[0] || {})}`);
627
+ throw new Error(`Uncaught exception in playground.html: ${JSON.stringify(exceptions[0] || {})}`);
598
628
  }
599
629
  }
600
630
 
@@ -777,11 +807,11 @@ ${JSON.stringify(last, null, 2)}`);
777
807
  ok('playground auto-loads a companion example builtin for URL-loaded Sudoku');
778
808
 
779
809
  // Ensure no uncaught runtime exceptions.
780
- assert.equal(exceptions.length, 0, `Uncaught exceptions in demo.html: ${JSON.stringify(exceptions[0] || {})}`);
810
+ assert.equal(exceptions.length, 0, `Uncaught exceptions in playground.html: ${JSON.stringify(exceptions[0] || {})}`);
781
811
 
782
812
  // Console errors are noisy and often indicate a broken UI.
783
813
  // (We suppress known noise like /favicon.ico on the server.)
784
- assert.equal(consoleErrors.length, 0, `Console errors in demo.html: ${JSON.stringify(consoleErrors[0] || {})}`);
814
+ assert.equal(consoleErrors.length, 0, `Console errors in playground.html: ${JSON.stringify(consoleErrors[0] || {})}`);
785
815
 
786
816
  // Cleanup.
787
817
  try {
package/tools/bundle.js CHANGED
@@ -141,9 +141,9 @@ function buildBundleSource({ autoRunMain }) {
141
141
  );
142
142
  out.push(' try { if (__outerSelf) __outerSelf.eyeling = __api; } catch (ignoredError) {}');
143
143
  out.push('');
144
- out.push(' // ---- demo.html compatibility ----');
144
+ out.push(' // ---- playground.html compatibility ----');
145
145
  out.push(' // The original monolithic eyeling.js exposed internal functions/flags as globals.');
146
- out.push(' // demo.html still uses these via importScripts(...) inside a web worker.');
146
+ out.push(' // playground.html still uses these via importScripts(...) inside a web worker.');
147
147
  out.push(' try {');
148
148
  out.push(' if (__outerSelf && __entry) {');
149
149
  out.push(' if (typeof __entry.lex === "function") __outerSelf.lex = __entry.lex;');