@jarenjs/studio 0.34.2 → 0.43.1
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/README.md +2 -1
- package/dist/types/assemble.d.ts +4 -1
- package/dist/types/component/editor.d.ts +1 -0
- package/dist/types/validate.d.ts +3 -0
- package/package.json +8 -7
- package/schemas/jaren-project.schema.json +1 -1
- package/src/assemble.js +10 -6
- package/src/component/editor.js +3 -0
- package/src/component/view.js +1 -0
- package/src/component/viewmodel.js +6 -4
- package/src/project.js +1 -0
- package/src/validate.js +6 -0
package/README.md
CHANGED
|
@@ -25,7 +25,8 @@ This package ships in two layers, the suite's convention:
|
|
|
25
25
|
host registers the DOM-touching islands — the live nested-app stage
|
|
26
26
|
(hot-update via `app.setState`) and the drag splitter — which are
|
|
27
27
|
browser-verified. Mounted live at the website's `#/project`, where `app`
|
|
28
|
-
files boot, `jslt`/`query` files run against a data file,
|
|
28
|
+
files boot, `jslt`/`query` files run against a data file, `contract`
|
|
29
|
+
files render their `describe()`/OpenAPI projections, and files are
|
|
29
30
|
added, renamed, deleted and opened from templates.
|
|
30
31
|
|
|
31
32
|
## The project document
|
package/dist/types/assemble.d.ts
CHANGED
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
* HOT-DISPATCH into a running app (no reboot, the user keeps scroll and
|
|
15
15
|
* inputs), while a `view`/`actions` change must reboot. It compares a
|
|
16
16
|
* STRUCTURAL key (an app doc minus its `state`) via the suite's own
|
|
17
|
-
* `
|
|
17
|
+
* `semanticKey` — the collision-free identity, not the memo-grade
|
|
18
|
+
* `contentKey` fingerprint: a classification decides whether a running
|
|
19
|
+
* app reboots, so a fingerprint collision would read a changed document
|
|
20
|
+
* as unchanged. The artifacts are parsed JSON, so the identity is total.
|
|
18
21
|
*/
|
|
19
22
|
/**
|
|
20
23
|
* Compose the project's files into runnable artifacts (whole-document).
|
package/dist/types/validate.d.ts
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
* real error comes back as its own coded `JQ`/`JT` code with
|
|
13
13
|
* a docPath — the closed grammar would reject the operators;
|
|
14
14
|
* - `fsm` / `dag` / `model` → their published grammar (structural);
|
|
15
|
+
* - `contract` → COMPILED by `compileContract`, so a refusal comes back
|
|
16
|
+
* as its stable `JC00xx` code with the docPath of the
|
|
17
|
+
* member at fault — richer than the grammar alone;
|
|
15
18
|
* - `schema` → compiled as a JSON Schema (is it well-formed?);
|
|
16
19
|
* - `state` / `data` → any JSON (structural only).
|
|
17
20
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jarenjs/studio",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.43.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./dist/types/index.d.ts",
|
|
@@ -59,11 +59,12 @@
|
|
|
59
59
|
"prepack": "npm run build:types"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@jarenjs/core": "^0.
|
|
63
|
-
"@jarenjs/validate": "^0.
|
|
64
|
-
"@jarenjs/json": "^0.
|
|
65
|
-
"@jarenjs/app": "^0.
|
|
66
|
-
"@jarenjs/flow": "^0.
|
|
67
|
-
"@jarenjs/db": "^0.
|
|
62
|
+
"@jarenjs/core": "^0.43.1",
|
|
63
|
+
"@jarenjs/validate": "^0.43.1",
|
|
64
|
+
"@jarenjs/json": "^0.43.1",
|
|
65
|
+
"@jarenjs/app": "^0.43.1",
|
|
66
|
+
"@jarenjs/flow": "^0.43.1",
|
|
67
|
+
"@jarenjs/db": "^0.43.1",
|
|
68
|
+
"@jarenjs/contract": "^0.43.1"
|
|
68
69
|
}
|
|
69
70
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"name": { "type": "string", "minLength": 1 },
|
|
29
29
|
"kind": {
|
|
30
30
|
"description": "The file's grammar/role; its `text` is validated against this kind, not the envelope.",
|
|
31
|
-
"enum": ["app", "jslt", "query", "state", "data", "schema", "fsm", "dag", "model"]
|
|
31
|
+
"enum": ["app", "jslt", "query", "state", "data", "schema", "fsm", "dag", "model", "contract"]
|
|
32
32
|
},
|
|
33
33
|
"text": { "type": "string" }
|
|
34
34
|
}
|
package/src/assemble.js
CHANGED
|
@@ -15,20 +15,24 @@
|
|
|
15
15
|
* HOT-DISPATCH into a running app (no reboot, the user keeps scroll and
|
|
16
16
|
* inputs), while a `view`/`actions` change must reboot. It compares a
|
|
17
17
|
* STRUCTURAL key (an app doc minus its `state`) via the suite's own
|
|
18
|
-
* `
|
|
18
|
+
* `semanticKey` — the collision-free identity, not the memo-grade
|
|
19
|
+
* `contentKey` fingerprint: a classification decides whether a running
|
|
20
|
+
* app reboots, so a fingerprint collision would read a changed document
|
|
21
|
+
* as unchanged. The artifacts are parsed JSON, so the identity is total.
|
|
19
22
|
*/
|
|
20
23
|
|
|
21
|
-
import {
|
|
24
|
+
import { semanticKey } from '@jarenjs/core/object';
|
|
22
25
|
import { validateFile } from './validate.js';
|
|
23
26
|
|
|
24
27
|
/** Kinds that are runnable artifacts on their own (vs. `state`/`data`
|
|
25
28
|
* inputs). */
|
|
26
|
-
const RUNNABLE = new Set(['app', 'jslt', 'query', 'schema', 'fsm', 'dag', 'model']);
|
|
29
|
+
const RUNNABLE = new Set(['app', 'jslt', 'query', 'schema', 'fsm', 'dag', 'model', 'contract']);
|
|
27
30
|
|
|
28
31
|
/** A human role per kind, for the file rail's legibility. */
|
|
29
32
|
const ROLE = Object.freeze({
|
|
30
33
|
app: 'application', jslt: 'transform', query: 'query', state: 'state',
|
|
31
34
|
data: 'data', schema: 'schema', fsm: 'state machine', dag: 'dataflow', model: 'data store',
|
|
35
|
+
contract: 'contract',
|
|
32
36
|
});
|
|
33
37
|
|
|
34
38
|
/**
|
|
@@ -59,8 +63,8 @@ export function assembleArtifacts(project) {
|
|
|
59
63
|
* (its `state` excluded); everything else in full. */
|
|
60
64
|
function structuralKey(artifact) {
|
|
61
65
|
return artifact.kind === 'app'
|
|
62
|
-
?
|
|
63
|
-
:
|
|
66
|
+
? semanticKey({ view: artifact.doc.view, actions: artifact.doc.actions, subs: artifact.doc.subs })
|
|
67
|
+
: semanticKey(artifact.doc);
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
const RANK = { none: 0, 'state-only': 1, structural: 2 };
|
|
@@ -88,7 +92,7 @@ export function classifyChange(prevProject, nextProject) {
|
|
|
88
92
|
let c;
|
|
89
93
|
if (b === undefined) c = 'structural';
|
|
90
94
|
else if (structuralKey(b) !== structuralKey(a)) c = 'structural';
|
|
91
|
-
else if (
|
|
95
|
+
else if (semanticKey(b.doc) !== semanticKey(a.doc)) c = 'state-only';
|
|
92
96
|
else c = 'none';
|
|
93
97
|
perArtifact[name] = c;
|
|
94
98
|
bump(c);
|
package/src/component/editor.js
CHANGED
|
@@ -56,4 +56,7 @@ export function errorLine(content) {
|
|
|
56
56
|
export const KIND_BADGE = Object.freeze({
|
|
57
57
|
app: 'view', jslt: 'view', query: 'query', state: 'json',
|
|
58
58
|
data: 'json', schema: 'json', model: 'model', fsm: 'flow', dag: 'flow',
|
|
59
|
+
// the model family: documents that declare a schema-backed surface —
|
|
60
|
+
// the badge palette is a closed five-hue set (studio.css header)
|
|
61
|
+
contract: 'model',
|
|
59
62
|
});
|
package/src/component/view.js
CHANGED
|
@@ -37,10 +37,12 @@ function deriveStage(project, activeMeta, results, revision, committed) {
|
|
|
37
37
|
// here it is the data: the assembled document + the reboot revision
|
|
38
38
|
return { kind: 'app', mount: { doc: artifact.doc, revision } };
|
|
39
39
|
}
|
|
40
|
-
if (activeMeta.kind === 'jslt' || activeMeta.kind === 'query' || activeMeta.kind === 'schema'
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
//
|
|
40
|
+
if (activeMeta.kind === 'jslt' || activeMeta.kind === 'query' || activeMeta.kind === 'schema'
|
|
41
|
+
|| activeMeta.kind === 'contract') {
|
|
42
|
+
// the host runs the file (a transform, a schema validating the data
|
|
43
|
+
// file, or a contract's describe()/OpenAPI projections) and stores
|
|
44
|
+
// its render nodes; the stage renders them in `ui` mode, or a hint
|
|
45
|
+
// until the first run lands
|
|
44
46
|
const result = results[activeMeta.name] ?? null;
|
|
45
47
|
return { kind: 'result', ran: result !== null, nodes: result?.nodes ?? [] };
|
|
46
48
|
}
|
package/src/project.js
CHANGED
|
@@ -15,6 +15,7 @@ import { StudioError } from './errors.js';
|
|
|
15
15
|
/** The closed set of file kinds (matches the schema `kind` enum). */
|
|
16
16
|
export const KINDS = Object.freeze([
|
|
17
17
|
'app', 'jslt', 'query', 'state', 'data', 'schema', 'fsm', 'dag', 'model',
|
|
18
|
+
'contract',
|
|
18
19
|
]);
|
|
19
20
|
|
|
20
21
|
/** The default IDE layout — the frozen `{ mode, ratio, autorun }` shape
|
package/src/validate.js
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
* real error comes back as its own coded `JQ`/`JT` code with
|
|
14
14
|
* a docPath — the closed grammar would reject the operators;
|
|
15
15
|
* - `fsm` / `dag` / `model` → their published grammar (structural);
|
|
16
|
+
* - `contract` → COMPILED by `compileContract`, so a refusal comes back
|
|
17
|
+
* as its stable `JC00xx` code with the docPath of the
|
|
18
|
+
* member at fault — richer than the grammar alone;
|
|
16
19
|
* - `schema` → compiled as a JSON Schema (is it well-formed?);
|
|
17
20
|
* - `state` / `data` → any JSON (structural only).
|
|
18
21
|
*
|
|
@@ -27,6 +30,7 @@ import { compileJsonQuery } from '@jarenjs/json';
|
|
|
27
30
|
import {
|
|
28
31
|
compileJsltStylesheet, createJsltRegistry, mathPack, financePack, statsPack,
|
|
29
32
|
} from '@jarenjs/json/jslt';
|
|
33
|
+
import { compileContract } from '@jarenjs/contract';
|
|
30
34
|
|
|
31
35
|
import appSchema from '@jarenjs/app/schemas/jaren-app.schema.json' with { type: 'json' };
|
|
32
36
|
import querySchema from '@jarenjs/json/schemas/jaren-query.schema.json' with { type: 'json' };
|
|
@@ -178,6 +182,8 @@ function validateFileUncached(file, options = {}) {
|
|
|
178
182
|
return schemaResult(kind, validateDag(doc));
|
|
179
183
|
case 'model':
|
|
180
184
|
return schemaResult(kind, validateModel(doc));
|
|
185
|
+
case 'contract':
|
|
186
|
+
return compileResult(kind, () => compileContract(doc));
|
|
181
187
|
case 'schema':
|
|
182
188
|
// a JSON Schema is a boolean or an object; anything else is not a
|
|
183
189
|
// schema at all (the compiler is otherwise lenient about a schema's
|