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 +2 -2
- package/README.md +1 -1
- package/dist/browser/eyeling.browser.js +10 -10
- package/examples/annotation.n3 +1 -1
- package/examples/deck/faltings-genus2-finiteness.md +1 -1
- package/examples/deck/high-trust-rdf-bloom-envelope.md +1 -1
- package/examples/deck/odrl-dpv-risk-ranked.md +1 -1
- package/examples/deck/schema-foaf-mapping.md +1 -1
- package/examples/output/annotation.md +14 -0
- package/eyeling.js +10 -10
- package/lib/engine.js +4 -4
- package/lib/entry.js +2 -2
- package/lib/printing.js +1 -1
- package/lib/trace.js +1 -1
- package/package.json +1 -1
- package/test/api.test.js +1 -1
- package/test/playground.test.js +45 -15
- package/tools/bundle.js +2 -2
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 `
|
|
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
|
|
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/
|
|
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
|
|
8901
|
+
// Internals (exposed for playground.html)
|
|
8902
8902
|
// ---------------------------------------------------------------------------
|
|
8903
8903
|
// The original monolithic eyeling.js exposed many internal functions and flags
|
|
8904
|
-
// as globals.
|
|
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
|
-
//
|
|
8949
|
+
// playground internals
|
|
8950
8950
|
forwardChain,
|
|
8951
8951
|
materializeRdfLists,
|
|
8952
8952
|
isGroundTriple,
|
|
8953
8953
|
printExplanation,
|
|
8954
|
-
// used by
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
// ----
|
|
13902
|
+
// ---- playground.html compatibility ----
|
|
13903
13903
|
// The original monolithic eyeling.js exposed internal functions/flags as globals.
|
|
13904
|
-
//
|
|
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/examples/annotation.n3
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
|
8901
|
+
// Internals (exposed for playground.html)
|
|
8902
8902
|
// ---------------------------------------------------------------------------
|
|
8903
8903
|
// The original monolithic eyeling.js exposed many internal functions and flags
|
|
8904
|
-
// as globals.
|
|
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
|
-
//
|
|
8949
|
+
// playground internals
|
|
8950
8950
|
forwardChain,
|
|
8951
8951
|
materializeRdfLists,
|
|
8952
8952
|
isGroundTriple,
|
|
8953
8953
|
printExplanation,
|
|
8954
|
-
// used by
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
// ----
|
|
13902
|
+
// ---- playground.html compatibility ----
|
|
13903
13903
|
// The original monolithic eyeling.js exposed internal functions/flags as globals.
|
|
13904
|
-
//
|
|
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
|
|
3583
|
+
// Internals (exposed for playground.html)
|
|
3584
3584
|
// ---------------------------------------------------------------------------
|
|
3585
3585
|
// The original monolithic eyeling.js exposed many internal functions and flags
|
|
3586
|
-
// as globals.
|
|
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
|
-
//
|
|
3631
|
+
// playground internals
|
|
3632
3632
|
forwardChain,
|
|
3633
3633
|
materializeRdfLists,
|
|
3634
3634
|
isGroundTriple,
|
|
3635
3635
|
printExplanation,
|
|
3636
|
-
// used by
|
|
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
|
|
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
|
|
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
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
|
|
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
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
|
|
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
|
|
package/test/playground.test.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// Smoke-test the browser playground (
|
|
3
|
+
// Smoke-test the browser playground (playground.html).
|
|
4
4
|
//
|
|
5
|
-
// Goal: ensure
|
|
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 = '/
|
|
59
|
+
if (pathname === '/' || pathname === '') pathname = '/playground.html';
|
|
60
60
|
// Prevent directory traversal.
|
|
61
|
-
|
|
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(/\/$/, '') + '/
|
|
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
|
|
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
|
|
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
|
|
421
|
-
|
|
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
|
|
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:
|
|
579
|
-
assert.ok(!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
|
|
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
|
|
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
|
|
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(' // ----
|
|
144
|
+
out.push(' // ---- playground.html compatibility ----');
|
|
145
145
|
out.push(' // The original monolithic eyeling.js exposed internal functions/flags as globals.');
|
|
146
|
-
out.push(' //
|
|
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;');
|