@listen-fire/movement-lang 0.12.0-rc.5 → 0.12.0-rc.7
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/dist/catalog/types.d.ts +3 -15
- package/dist/catalog/types.js +5 -5
- package/dist/checker/rust_checker.d.ts +15 -4
- package/dist/checker/rust_checker.js +37 -3
- package/dist/expression/bridge.d.ts +6 -5
- package/dist/expression/order_limit.js +1 -1
- package/dist/expression/types.d.ts +2 -2
- package/dist/language_version.d.ts +20 -50
- package/dist/language_version.js +63 -103
- package/dist/language_version_value.d.ts +1 -0
- package/dist/language_version_value.js +8 -0
- package/dist/parser/ast.d.ts +24 -28
- package/dist/parser/expression/lower.d.ts +7 -6
- package/dist/parser/expression/lower.js +3 -3
- package/dist/parser/expression/parse_expression.d.ts +2 -1
- package/dist/parser/expression/tree.d.ts +1 -1
- package/dist/parser/parse.d.ts +5 -4
- package/dist/parser/parse.js +3 -3
- package/dist/parser/rust_parser.d.ts +11 -8
- package/dist/parser/rust_parser.js +27 -17
- package/dist/parser/surface.d.ts +21 -22
- package/dist/parser/surface.js +25 -31
- package/dist/service/snapshot.js +1 -1
- package/dist/wasm/loader.d.ts +31 -5
- package/dist/wasm/loader.js +30 -8
- package/dist/wasm/movement.wasm +0 -0
- package/dist/wasm/movement_parser.wasm +0 -0
- package/package.json +2 -2
package/dist/catalog/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { LanguageVersion } from '../language_version';
|
|
2
1
|
import type { EdgeCapability, EdgeSequencing, Expression, FieldCapability } from '../expression/types';
|
|
3
2
|
/**
|
|
4
3
|
* One argument in an adapter's construction signature. The list is the full
|
|
@@ -277,16 +276,6 @@ export interface PluginSpec {
|
|
|
277
276
|
* goes to the extractor, not to a name.
|
|
278
277
|
*/
|
|
279
278
|
output?: PluginOutput;
|
|
280
|
-
/**
|
|
281
|
-
* The shapes `output` had before it changed: each is what a plain call hands
|
|
282
|
-
* back to a program pinned before language version `before`, earliest
|
|
283
|
-
* first. A call is typed under its program's pin (`pluginOutputUnder`);
|
|
284
|
-
* removing a language version removes its entries.
|
|
285
|
-
*/
|
|
286
|
-
earlierOutputs?: ReadonlyArray<{
|
|
287
|
-
before: LanguageVersion;
|
|
288
|
-
output: PluginOutput;
|
|
289
|
-
}>;
|
|
290
279
|
/** The package tag it is a member of (`@lf/web`), matched exactly
|
|
291
280
|
* (`packageMembers`); absent when it is in none. */
|
|
292
281
|
package?: string;
|
|
@@ -313,7 +302,7 @@ export declare function pluginKey(packageTag: string, name: string): string;
|
|
|
313
302
|
export declare function pluginProgramNameOf(key: string, spec: PluginSpec): string;
|
|
314
303
|
/** What a written plugin name stands for among `plugins`: the entry keyed by
|
|
315
304
|
* exactly that (a package member's key), else the one entry whose name it is
|
|
316
|
-
* (a bare import, as
|
|
305
|
+
* (a bare import, as the older language writes it); several such are `ambiguous`,
|
|
317
306
|
* listing the packages that serve it. The Rust twin is `find_plugin`. */
|
|
318
307
|
export declare function findPlugin(plugins: Readonly<Record<string, PluginSpec>>, name: string): {
|
|
319
308
|
found: {
|
|
@@ -519,7 +508,7 @@ export interface EdgeSchema {
|
|
|
519
508
|
* The edge is the one the system declared as its records' resources (the
|
|
520
509
|
* describe's reserved `_resources` reference — the knowledge graph's
|
|
521
510
|
* `Resources`). An ordinary edge, walked by its name like any other; what
|
|
522
|
-
* the flag records is that
|
|
511
|
+
* the flag records is that an older `x-[f:_resources]->` on this
|
|
523
512
|
* system read it, so MOV_RESOURCES_NOT_EXTRACTED can name it. Diagnostics
|
|
524
513
|
* only: nothing resolves `_resources` to it.
|
|
525
514
|
*/
|
|
@@ -662,8 +651,7 @@ export interface PositionSchema {
|
|
|
662
651
|
/**
|
|
663
652
|
* A record of this type can be DELETED — the system's own promise, declared
|
|
664
653
|
* per type in its describe (`deletable: true`) where its `deleteRecord`
|
|
665
|
-
* removes one. Absent ⇒ it makes no such promise, and
|
|
666
|
-
* version 5 `delete x` of this type is MOV_DELETE_NOT_DECLARED (an
|
|
654
|
+
* removes one. Absent ⇒ it makes no such promise, and `delete x` of this type is MOV_DELETE_NOT_DECLARED (an
|
|
667
655
|
* undescribed or pending position says nothing, so nothing is refused).
|
|
668
656
|
*/
|
|
669
657
|
deletable?: boolean;
|
package/dist/catalog/types.js
CHANGED
|
@@ -76,15 +76,15 @@ function unquoteConstructionArg(raw) {
|
|
|
76
76
|
}
|
|
77
77
|
return trimmed;
|
|
78
78
|
}
|
|
79
|
-
// ── A plugin's arguments by position (
|
|
79
|
+
// ── A plugin's arguments by position (design §2.7) ──
|
|
80
80
|
//
|
|
81
81
|
// Its required inputs in the manifest's declared order, then one optional
|
|
82
82
|
// settings record `{ name: value }` for the rest. Binding turns that call into
|
|
83
|
-
// the named arguments
|
|
83
|
+
// the named arguments the older language writes, so every check and the wire to the
|
|
84
84
|
// plugin read one form. The Rust twin is `PluginSpec::bind_args`
|
|
85
85
|
// (crates/movement-parser/src/catalog/plugin_args.rs); both checkers and both
|
|
86
86
|
// engines bind through these two and nothing else.
|
|
87
|
-
// ── A plugin package (
|
|
87
|
+
// ── A plugin package (design §2.10, §4.3) ──
|
|
88
88
|
//
|
|
89
89
|
// A tag a plugin's spec declares as its `package`, matched exactly and never
|
|
90
90
|
// parsed. ``import { `@lf/web` as web } from plugins`` binds each member under
|
|
@@ -102,7 +102,7 @@ function pluginProgramNameOf(key, spec) {
|
|
|
102
102
|
}
|
|
103
103
|
/** What a written plugin name stands for among `plugins`: the entry keyed by
|
|
104
104
|
* exactly that (a package member's key), else the one entry whose name it is
|
|
105
|
-
* (a bare import, as
|
|
105
|
+
* (a bare import, as the older language writes it); several such are `ambiguous`,
|
|
106
106
|
* listing the packages that serve it. The Rust twin is `find_plugin`. */
|
|
107
107
|
function findPlugin(plugins, name) {
|
|
108
108
|
const exact = Object.hasOwn(plugins, name) ? plugins[name] : undefined;
|
|
@@ -148,7 +148,7 @@ function refinementKey(input) {
|
|
|
148
148
|
}
|
|
149
149
|
/**
|
|
150
150
|
* The filter with its field reads' `fieldOnly` marks dropped. The mark says
|
|
151
|
-
* how a read was SPELLED — through the hop's alias
|
|
151
|
+
* how a read was SPELLED — through the hop's alias
|
|
152
152
|
* (`e.action`), bare before (`action`) — and both spellings name the same
|
|
153
153
|
* field, so the key must not tell them apart: a host registers its narrowing
|
|
154
154
|
* once, from its own filter, and every version's program must find it.
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type LanguageVersion, type LanguageVersionStanding } from '../language_version';
|
|
2
2
|
import type { CatalogSnapshot } from '../service/snapshot';
|
|
3
3
|
import type { Diagnostic } from './diagnostic';
|
|
4
4
|
export interface RustCheckOptions {
|
|
5
|
+
/** The movement's pin, held to the rule before the artifact is asked: the
|
|
6
|
+
* artifact checks in its own release's language. */
|
|
5
7
|
languageVersion: LanguageVersion;
|
|
6
|
-
/** Checking for a move up from this
|
|
8
|
+
/** Checking for a move up from this release (`CheckOptions.upgradingFrom`). */
|
|
7
9
|
upgradingFrom?: LanguageVersion;
|
|
8
10
|
}
|
|
9
11
|
/** A source the Rust checker could not check: it does not parse, or the
|
|
@@ -11,8 +13,18 @@ export interface RustCheckOptions {
|
|
|
11
13
|
export declare class RustCheckRefused extends Error {
|
|
12
14
|
constructor(message: string);
|
|
13
15
|
}
|
|
16
|
+
/** The language the artifact reads: its release's version. */
|
|
17
|
+
export declare function languageVersion(): LanguageVersion;
|
|
18
|
+
/** How `pin` stands against the artifact's release, and the refusal's text
|
|
19
|
+
* when it does not read it (the rule in Rust: the drift test holds it equal
|
|
20
|
+
* to `languageVersionStanding`). */
|
|
21
|
+
export declare function languageStanding(pin: string): {
|
|
22
|
+
standing: LanguageVersionStanding;
|
|
23
|
+
message: string | null;
|
|
24
|
+
};
|
|
14
25
|
/** Every diagnostic the Rust checker reports for `source` against
|
|
15
|
-
* `snapshot`, warnings and info included.
|
|
26
|
+
* `snapshot`, warnings and info included. A pin this release does not read
|
|
27
|
+
* is its standing diagnostic alone, the artifact not asked. */
|
|
16
28
|
export declare function checkSourceInRust(source: string, snapshot: CatalogSnapshot, options: RustCheckOptions): Diagnostic[];
|
|
17
29
|
/** A checker fact about one node, keyed by its AST path (a JSON Pointer from
|
|
18
30
|
* the Program, `file` naming a library's): a write spread's field list, a
|
|
@@ -66,7 +78,6 @@ export declare function checkAnswerInRust(source: string, snapshot: CatalogSnaps
|
|
|
66
78
|
* when the schema enumerates nothing at the record type. */
|
|
67
79
|
export declare function compatibleInRust(request: {
|
|
68
80
|
source: string;
|
|
69
|
-
languageVersion: LanguageVersion;
|
|
70
81
|
declaration: string;
|
|
71
82
|
schema: unknown;
|
|
72
83
|
recordType: string;
|
|
@@ -10,10 +10,13 @@
|
|
|
10
10
|
// editor's live diagnostics stay on the TypeScript checker.
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.RustCheckRefused = void 0;
|
|
13
|
+
exports.languageVersion = languageVersion;
|
|
14
|
+
exports.languageStanding = languageStanding;
|
|
13
15
|
exports.checkSourceInRust = checkSourceInRust;
|
|
14
16
|
exports.checkAnswerInRust = checkAnswerInRust;
|
|
15
17
|
exports.compatibleInRust = compatibleInRust;
|
|
16
18
|
const loader_1 = require("../wasm/loader");
|
|
19
|
+
const language_version_1 = require("../language_version");
|
|
17
20
|
/** A source the Rust checker could not check: it does not parse, or the
|
|
18
21
|
* snapshot does not load. */
|
|
19
22
|
class RustCheckRefused extends Error {
|
|
@@ -23,10 +26,35 @@ class RustCheckRefused extends Error {
|
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
exports.RustCheckRefused = RustCheckRefused;
|
|
29
|
+
/** The language the artifact reads: its release's version. */
|
|
30
|
+
function languageVersion() {
|
|
31
|
+
const reply = (0, loader_1.callLanguageVersion)();
|
|
32
|
+
if (!reply.ok || typeof reply.json !== 'string')
|
|
33
|
+
throw new Error(`language_version: ${JSON.stringify(reply.json)}`);
|
|
34
|
+
return reply.json;
|
|
35
|
+
}
|
|
36
|
+
/** How `pin` stands against the artifact's release, and the refusal's text
|
|
37
|
+
* when it does not read it (the rule in Rust: the drift test holds it equal
|
|
38
|
+
* to `languageVersionStanding`). */
|
|
39
|
+
function languageStanding(pin) {
|
|
40
|
+
const reply = (0, loader_1.callLanguageStanding)(pin);
|
|
41
|
+
const json = reply.json;
|
|
42
|
+
if (!reply.ok || !isRecord(json) || !isStanding(json.standing) || (json.message !== null && typeof json.message !== 'string')) {
|
|
43
|
+
throw new Error(`language_standing: ${JSON.stringify(json)}`);
|
|
44
|
+
}
|
|
45
|
+
return { standing: json.standing, message: json.message };
|
|
46
|
+
}
|
|
47
|
+
function isStanding(value) {
|
|
48
|
+
return value === 'compatible' || value === 'newer' || value === 'olderKey' || value === 'malformed';
|
|
49
|
+
}
|
|
26
50
|
/** Every diagnostic the Rust checker reports for `source` against
|
|
27
|
-
* `snapshot`, warnings and info included.
|
|
51
|
+
* `snapshot`, warnings and info included. A pin this release does not read
|
|
52
|
+
* is its standing diagnostic alone, the artifact not asked. */
|
|
28
53
|
function checkSourceInRust(source, snapshot, options) {
|
|
29
|
-
const
|
|
54
|
+
const refusal = (0, language_version_1.languageVersionDiagnostic)(options.languageVersion);
|
|
55
|
+
if (refusal !== undefined)
|
|
56
|
+
return [refusal];
|
|
57
|
+
const reply = (0, loader_1.callCheckProgram)(source, JSON.stringify(snapshot), callOptions(options));
|
|
30
58
|
const json = reply.json;
|
|
31
59
|
if (!reply.ok)
|
|
32
60
|
throw refused(json);
|
|
@@ -37,7 +65,10 @@ function checkSourceInRust(source, snapshot, options) {
|
|
|
37
65
|
}
|
|
38
66
|
/** `checkSourceInRust` as data (crates/movement-checker/src/answer.rs). */
|
|
39
67
|
function checkAnswerInRust(source, snapshot, options) {
|
|
40
|
-
const
|
|
68
|
+
const refusal = (0, language_version_1.languageVersionDiagnostic)(options.languageVersion);
|
|
69
|
+
if (refusal !== undefined)
|
|
70
|
+
return { diagnostics: [refusal], stamps: [] };
|
|
71
|
+
const reply = (0, loader_1.callCheckAnswer)(source, JSON.stringify(snapshot), callOptions(options));
|
|
41
72
|
const json = reply.json;
|
|
42
73
|
if (!reply.ok)
|
|
43
74
|
throw refused(json);
|
|
@@ -65,6 +96,9 @@ function compatibleInRust(request) {
|
|
|
65
96
|
return { fits: json.fits };
|
|
66
97
|
throw new Error(`the Rust checker answered check.compatible with ${JSON.stringify(json)}`);
|
|
67
98
|
}
|
|
99
|
+
function callOptions(options) {
|
|
100
|
+
return options.upgradingFrom === undefined ? {} : { upgradingFrom: options.upgradingFrom };
|
|
101
|
+
}
|
|
68
102
|
function refused(json) {
|
|
69
103
|
const error = isRecord(json) && isRecord(json.error) ? json.error : undefined;
|
|
70
104
|
return new RustCheckRefused(typeof error?.message === 'string' ? error.message : 'the Rust checker refused the check');
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { Expression } from './types';
|
|
2
2
|
import type { ExprSlot } from '../parser/ast';
|
|
3
|
+
import type { LanguageVersion } from '../language_version';
|
|
3
4
|
import { type MovementCondition } from '../parser/expression/lower';
|
|
4
5
|
import type { MExpr } from '../parser/expression/tree';
|
|
5
6
|
export { BridgeError } from './error';
|
|
6
7
|
export { POSITION_SENTINEL, type MovementCondition } from '../parser/expression/lower';
|
|
7
|
-
export declare function parseMovementExpression(raw: string, languageVersion?:
|
|
8
|
-
export declare function parseMovementCondition(raw: string, languageVersion?:
|
|
8
|
+
export declare function parseMovementExpression(raw: string, languageVersion?: LanguageVersion): Expression;
|
|
9
|
+
export declare function parseMovementCondition(raw: string, languageVersion?: LanguageVersion): MovementCondition;
|
|
9
10
|
/** The slot's tree as the grammar read it, before lowering decides what any
|
|
10
11
|
* name in it means — what call resolution walks. Throws the slot's syntax
|
|
11
12
|
* error, as the lowerings below do. */
|
|
12
|
-
export declare function treeOfSlot(slot: ExprSlot, languageVersion?:
|
|
13
|
+
export declare function treeOfSlot(slot: ExprSlot, languageVersion?: LanguageVersion): MExpr;
|
|
13
14
|
/**
|
|
14
15
|
* A slot whose tree is `tree` — a rewriting of `slot`'s own tree (a nested
|
|
15
16
|
* call replaced by the name it is bound to), or one of its sub-expressions.
|
|
@@ -23,9 +24,9 @@ export declare function slotOfTree(slot: ExprSlot, tree: MExpr): ExprSlot;
|
|
|
23
24
|
* original's offsets, so a place in one is the same place in the other. */
|
|
24
25
|
export declare function originalSlot(slot: ExprSlot): ExprSlot;
|
|
25
26
|
/** The slot as a value expression. */
|
|
26
|
-
export declare function expressionOfSlot(slot: ExprSlot, languageVersion?:
|
|
27
|
+
export declare function expressionOfSlot(slot: ExprSlot, languageVersion?: LanguageVersion): Expression;
|
|
27
28
|
/** The slot as an `if` condition. */
|
|
28
|
-
export declare function conditionOfSlot(slot: ExprSlot, languageVersion?:
|
|
29
|
+
export declare function conditionOfSlot(slot: ExprSlot, languageVersion?: LanguageVersion): MovementCondition;
|
|
29
30
|
/**
|
|
30
31
|
* A string slot's text for a READER — the story, a diagnostic, a listing.
|
|
31
32
|
* A literal that interpolates has no text until it is evaluated in a firing
|
|
@@ -72,7 +72,7 @@ function hopOrderProperty(cardinality) {
|
|
|
72
72
|
async function sortByOrderKey(items, direction, options) {
|
|
73
73
|
// Every key read settles before any failure is thrown, and the failure is
|
|
74
74
|
// the earliest by position, not the first to arrive: the Rust engine and
|
|
75
|
-
// apps/api
|
|
75
|
+
// lf-platform's apps/api settle-all (fans.ts, which this package cannot import) fail the
|
|
76
76
|
// same way, so a run fails identically whatever order the reads land in.
|
|
77
77
|
const outcomes = await Promise.allSettled(items.map(async (item, index) => ({ item, index, key: await options.value(item) })));
|
|
78
78
|
const keyed = [];
|
|
@@ -299,10 +299,10 @@ export declare function objectMemberExpression(member: ObjectMember): Expression
|
|
|
299
299
|
/** An object member rebuilt with `rewrite` applied to its expression. */
|
|
300
300
|
export declare function mapObjectMember(member: ObjectMember, rewrite: (expr: Expression) => Expression): ObjectMember;
|
|
301
301
|
export type Expression =
|
|
302
|
-
/** `fieldOnly`: a hop's alias read
|
|
302
|
+
/** `fieldOnly`: a hop's alias read (`m.email`),
|
|
303
303
|
* always the field of the record the hop lands on. Without it a name in a
|
|
304
304
|
* hop's WHERE is a variable when one is in scope, else the field (the
|
|
305
|
-
* reading
|
|
305
|
+
* reading the older language keeps). A source given the filter reads both as the
|
|
306
306
|
* field, as it always has. */
|
|
307
307
|
{
|
|
308
308
|
type: 'property';
|
|
@@ -1,58 +1,28 @@
|
|
|
1
1
|
import type { Diagnostic } from './checker/diagnostic';
|
|
2
|
-
/** A
|
|
3
|
-
export type LanguageVersion =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export declare
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
export declare const CURRENT_LANGUAGE_VERSION: LanguageVersion;
|
|
15
|
-
/** The versions this release parses, checks and runs. */
|
|
16
|
-
export declare const SUPPORTED_LANGUAGE_VERSIONS: ReadonlySet<LanguageVersion>;
|
|
17
|
-
/** Supported versions that will be removed: they still run, with a warning. */
|
|
18
|
-
export declare const DEPRECATED_LANGUAGE_VERSIONS: ReadonlySet<LanguageVersion>;
|
|
19
|
-
/** What a release declares about versions. The standing of a pin is a question
|
|
20
|
-
* asked of a release, so a deploy check can ask it of the next one. */
|
|
21
|
-
export interface LanguageRelease {
|
|
22
|
-
current: LanguageVersion;
|
|
23
|
-
supported: ReadonlySet<LanguageVersion>;
|
|
24
|
-
deprecated: ReadonlySet<LanguageVersion>;
|
|
25
|
-
}
|
|
26
|
-
export declare const THIS_RELEASE: LanguageRelease;
|
|
27
|
-
export declare function languageVersionInfo(version: LanguageVersion): LanguageVersionInfo | undefined;
|
|
28
|
-
/** `"Quiet Heron" (1)` — or `version 7` for an integer this release has never
|
|
29
|
-
* heard of (a movement saved by a newer release). */
|
|
30
|
-
export declare function describeLanguageVersion(version: LanguageVersion): string;
|
|
31
|
-
/** How a version is shown to a person or an agent: the integer that identifies
|
|
32
|
-
* it, and its name. */
|
|
33
|
-
export interface LanguageVersionView {
|
|
34
|
-
version: LanguageVersion;
|
|
35
|
-
name: string;
|
|
36
|
-
}
|
|
37
|
-
export declare function languageVersionView(version: LanguageVersion): LanguageVersionView;
|
|
38
|
-
export type LanguageVersionStanding = 'supported' | 'deprecated' | 'unsupported';
|
|
39
|
-
export declare function languageVersionStanding(version: LanguageVersion, release?: LanguageRelease): LanguageVersionStanding;
|
|
2
|
+
/** A pin: the release a movement was written against, `MAJOR.MINOR.PATCH[-pre]`. */
|
|
3
|
+
export type LanguageVersion = string;
|
|
4
|
+
/** This release's version, and so the language it reads. */
|
|
5
|
+
export declare const LANGUAGE_VERSION: LanguageVersion;
|
|
6
|
+
export type LanguageVersionStanding = 'compatible' | 'newer' | 'olderKey' | 'malformed';
|
|
7
|
+
/** The part of a version a pin must share with a release; undefined for a
|
|
8
|
+
* text that is not a version. */
|
|
9
|
+
export declare function compatibilityKey(version: string): string | undefined;
|
|
10
|
+
/** How `pin` stands against the release `own`. */
|
|
11
|
+
export declare function languageVersionStanding(pin: string, own?: LanguageVersion): LanguageVersionStanding;
|
|
12
|
+
/** Whether the release `own` reads a movement pinned to `pin`. */
|
|
13
|
+
export declare function compatible(pin: string, own?: LanguageVersion): boolean;
|
|
40
14
|
export declare const LanguageVersionDiagnosticCodes: {
|
|
41
15
|
readonly UNSUPPORTED: "MOV_LANGUAGE_VERSION_UNSUPPORTED";
|
|
42
|
-
readonly DEPRECATED: "MOV_LANGUAGE_VERSION_DEPRECATED";
|
|
43
16
|
};
|
|
44
17
|
/**
|
|
45
|
-
* What a movement pinned to `
|
|
46
|
-
*
|
|
47
|
-
* version),
|
|
48
|
-
* The message names the version and the fix.
|
|
18
|
+
* What a movement pinned to `pin` must be told before anything else: an error
|
|
19
|
+
* when this release does not read it (never a silent fallback to the current
|
|
20
|
+
* version), naming the pin and the remedy; nothing when it does.
|
|
49
21
|
*/
|
|
50
|
-
export declare function languageVersionDiagnostic(
|
|
51
|
-
/** The run host's units (Henry 2026-10-16):
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
22
|
+
export declare function languageVersionDiagnostic(pin: string, own?: LanguageVersion): Diagnostic | undefined;
|
|
23
|
+
/** The run host's units (Henry 2026-10-16): every file has these names in
|
|
24
|
+
* scope, each already connected — `listen to manual fire hello`,
|
|
25
|
+
* `listen to cron { schedule: "0 9 * * 1" } fire digest` — with no import
|
|
26
|
+
* and no `connect`. A file's own binding of the name replaces it.
|
|
55
27
|
* (`RUN_HOST_UNITS` in crates/movement-parser/src/version.rs.) */
|
|
56
28
|
export declare const RUN_HOST_UNITS: readonly string[];
|
|
57
|
-
/** The units a file pinned to `version` has in scope. */
|
|
58
|
-
export declare function runHostUnits(version: LanguageVersion): readonly string[];
|
package/dist/language_version.js
CHANGED
|
@@ -1,123 +1,83 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
//
|
|
2
|
+
// The language version is the toolchain release: the one semver every crate
|
|
3
|
+
// and package carries. A movement's pin is the release it was written
|
|
4
|
+
// against, and a release reads a pin whose compatibility key is its own: the
|
|
5
|
+
// minor under 0.x (`0.12`), the major from 1.0 (`1`). Any other pin is refused
|
|
6
|
+
// by name, with the remedy (docs/contracts/language-versions.md).
|
|
3
7
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// by a conditional at the point of difference:
|
|
7
|
-
//
|
|
8
|
-
// if (ctx.languageVersion < 2) { …the old behaviour… }
|
|
9
|
-
//
|
|
10
|
-
// The integer is the identity — code compares it and never parses the name.
|
|
11
|
-
// The name is display only: it is what a person sees.
|
|
12
|
-
//
|
|
13
|
-
// A version keeps its row here after it leaves SUPPORTED, so a movement pinned
|
|
14
|
-
// to it can still be refused by name.
|
|
15
|
-
//
|
|
16
|
-
// See plans/language-versioning-2026-09-29/.
|
|
8
|
+
// The same rule is crates/movement-parser/src/version.rs; a test holds the two
|
|
9
|
+
// equal (packages/engine-contracts/__test__/contracts.unit.test.ts).
|
|
17
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.RUN_HOST_UNITS = exports.LanguageVersionDiagnosticCodes = exports.
|
|
19
|
-
exports.
|
|
20
|
-
exports.describeLanguageVersion = describeLanguageVersion;
|
|
21
|
-
exports.languageVersionView = languageVersionView;
|
|
11
|
+
exports.RUN_HOST_UNITS = exports.LanguageVersionDiagnosticCodes = exports.LANGUAGE_VERSION = void 0;
|
|
12
|
+
exports.compatibilityKey = compatibilityKey;
|
|
22
13
|
exports.languageVersionStanding = languageVersionStanding;
|
|
14
|
+
exports.compatible = compatible;
|
|
23
15
|
exports.languageVersionDiagnostic = languageVersionDiagnostic;
|
|
24
|
-
|
|
16
|
+
const language_version_value_1 = require("./language_version_value");
|
|
25
17
|
const never_1 = require("./never");
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
is: 'the language from v0.10.0: a list literal is a tuple — exact at a literal index, a list of its members\' union elsewhere',
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
version: 4,
|
|
36
|
-
name: 'Luminous Owl',
|
|
37
|
-
is: 'the language from v0.11.0: a match yields absent on a miss, a write handle reaches its pre-write record through @old',
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
version: 5,
|
|
41
|
-
name: 'Dancing Wren',
|
|
42
|
-
is: 'the language after v0.11.0: no engine-side store and no meta edges — no `write … bind` (a link lives in the system that holds it), no `#` hops (a plugin is a function you call), `delete` only where the system declares a type deletable, `_resources` only on an extraction\'s result (a record walks its system\'s file edge: `Attachments`, `Files`, `Resources`), a file is never joined into text (its text is `READ(f)`), a closure is a value (a list may hold closures, and a value that is one is called), and `parallel` is retired (`MAP` over the functions, calling each, is the join)',
|
|
43
|
-
},
|
|
44
|
-
];
|
|
45
|
-
/** What a movement saved today is pinned to, and what an entry point given no
|
|
46
|
-
* version compiles and runs under. */
|
|
47
|
-
exports.CURRENT_LANGUAGE_VERSION = 5;
|
|
48
|
-
/** The versions this release parses, checks and runs. */
|
|
49
|
-
exports.SUPPORTED_LANGUAGE_VERSIONS = new Set([5]);
|
|
50
|
-
/** Supported versions that will be removed: they still run, with a warning. */
|
|
51
|
-
exports.DEPRECATED_LANGUAGE_VERSIONS = new Set();
|
|
52
|
-
exports.THIS_RELEASE = {
|
|
53
|
-
current: exports.CURRENT_LANGUAGE_VERSION,
|
|
54
|
-
supported: exports.SUPPORTED_LANGUAGE_VERSIONS,
|
|
55
|
-
deprecated: exports.DEPRECATED_LANGUAGE_VERSIONS,
|
|
56
|
-
};
|
|
57
|
-
function languageVersionInfo(version) {
|
|
58
|
-
return exports.LANGUAGE_VERSIONS.find((info) => info.version === version);
|
|
18
|
+
/** This release's version, and so the language it reads. */
|
|
19
|
+
exports.LANGUAGE_VERSION = language_version_value_1.PACKAGE_VERSION;
|
|
20
|
+
const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
21
|
+
function parse(version) {
|
|
22
|
+
const match = SEMVER.exec(version);
|
|
23
|
+
return match === null ? undefined : { major: Number(match[1]), minor: Number(match[2]) };
|
|
59
24
|
}
|
|
60
|
-
/**
|
|
61
|
-
*
|
|
62
|
-
function
|
|
63
|
-
const
|
|
64
|
-
|
|
25
|
+
/** The part of a version a pin must share with a release; undefined for a
|
|
26
|
+
* text that is not a version. */
|
|
27
|
+
function compatibilityKey(version) {
|
|
28
|
+
const parsed = parse(version);
|
|
29
|
+
if (parsed === undefined)
|
|
30
|
+
return undefined;
|
|
31
|
+
return parsed.major === 0 ? `0.${parsed.minor}` : String(parsed.major);
|
|
65
32
|
}
|
|
66
|
-
|
|
67
|
-
|
|
33
|
+
/** How `pin` stands against the release `own`. */
|
|
34
|
+
function languageVersionStanding(pin, own = exports.LANGUAGE_VERSION) {
|
|
35
|
+
const pinned = parse(pin);
|
|
36
|
+
const release = parse(own);
|
|
37
|
+
if (pinned === undefined || release === undefined)
|
|
38
|
+
return 'malformed';
|
|
39
|
+
if (compatibilityKey(pin) === compatibilityKey(own))
|
|
40
|
+
return 'compatible';
|
|
41
|
+
const newer = pinned.major !== release.major ? pinned.major > release.major : pinned.minor > release.minor;
|
|
42
|
+
return newer ? 'newer' : 'olderKey';
|
|
68
43
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (release.deprecated.has(version))
|
|
73
|
-
return 'deprecated';
|
|
74
|
-
return 'supported';
|
|
44
|
+
/** Whether the release `own` reads a movement pinned to `pin`. */
|
|
45
|
+
function compatible(pin, own = exports.LANGUAGE_VERSION) {
|
|
46
|
+
return languageVersionStanding(pin, own) === 'compatible';
|
|
75
47
|
}
|
|
76
48
|
exports.LanguageVersionDiagnosticCodes = {
|
|
77
49
|
UNSUPPORTED: 'MOV_LANGUAGE_VERSION_UNSUPPORTED',
|
|
78
|
-
DEPRECATED: 'MOV_LANGUAGE_VERSION_DEPRECATED',
|
|
79
50
|
};
|
|
80
|
-
|
|
81
|
-
* What a movement pinned to `version` must be told before anything else: an
|
|
82
|
-
* error when this release cannot run it (never a silent fallback to the current
|
|
83
|
-
* version), a warning when it runs but will stop doing so, nothing otherwise.
|
|
84
|
-
* The message names the version and the fix.
|
|
85
|
-
*/
|
|
86
|
-
function languageVersionDiagnostic(version, release = exports.THIS_RELEASE) {
|
|
87
|
-
const span = { start: { line: 1, col: 1 }, end: { line: 1, col: 1 } };
|
|
88
|
-
const current = describeLanguageVersion(release.current);
|
|
89
|
-
const standing = languageVersionStanding(version, release);
|
|
51
|
+
function refusalMessage(pin, own, standing) {
|
|
90
52
|
switch (standing) {
|
|
91
|
-
case '
|
|
92
|
-
return
|
|
93
|
-
case '
|
|
94
|
-
return {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
`which this release does not support, so it will not validate or run. ` +
|
|
98
|
-
`To fix: validate it under ${current}, repair what that reports, and upgrade it to ${current}.`,
|
|
99
|
-
span,
|
|
100
|
-
};
|
|
101
|
-
case 'deprecated':
|
|
102
|
-
return {
|
|
103
|
-
code: exports.LanguageVersionDiagnosticCodes.DEPRECATED,
|
|
104
|
-
message: `this automation is written in language version ${describeLanguageVersion(version)}, ` +
|
|
105
|
-
`which is deprecated and will be removed in a future release. ` +
|
|
106
|
-
`Validate it under ${current}, repair what that reports, and upgrade it to ${current} before then.`,
|
|
107
|
-
span,
|
|
108
|
-
severity: 'warning',
|
|
109
|
-
};
|
|
53
|
+
case 'newer':
|
|
54
|
+
return `this automation pins language ${pin}, newer than this release (${own}); upgrade the engine`;
|
|
55
|
+
case 'olderKey':
|
|
56
|
+
return `this automation pins language ${pin}, which this release (${own}) does not read; validate it under ${own} and upgrade it`;
|
|
57
|
+
case 'malformed':
|
|
58
|
+
return `this automation pins language ${pin}, which is not a version; a pin is a release's version, such as ${own}`;
|
|
110
59
|
default:
|
|
111
60
|
return (0, never_1.neverAsAny)(standing);
|
|
112
61
|
}
|
|
113
62
|
}
|
|
114
|
-
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
63
|
+
/**
|
|
64
|
+
* What a movement pinned to `pin` must be told before anything else: an error
|
|
65
|
+
* when this release does not read it (never a silent fallback to the current
|
|
66
|
+
* version), naming the pin and the remedy; nothing when it does.
|
|
67
|
+
*/
|
|
68
|
+
function languageVersionDiagnostic(pin, own = exports.LANGUAGE_VERSION) {
|
|
69
|
+
const standing = languageVersionStanding(pin, own);
|
|
70
|
+
if (standing === 'compatible')
|
|
71
|
+
return undefined;
|
|
72
|
+
return {
|
|
73
|
+
code: exports.LanguageVersionDiagnosticCodes.UNSUPPORTED,
|
|
74
|
+
message: refusalMessage(pin, own, standing),
|
|
75
|
+
span: { start: { line: 1, col: 1 }, end: { line: 1, col: 1 } },
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** The run host's units (Henry 2026-10-16): every file has these names in
|
|
79
|
+
* scope, each already connected — `listen to manual fire hello`,
|
|
80
|
+
* `listen to cron { schedule: "0 9 * * 1" } fire digest` — with no import
|
|
81
|
+
* and no `connect`. A file's own binding of the name replaces it.
|
|
118
82
|
* (`RUN_HOST_UNITS` in crates/movement-parser/src/version.rs.) */
|
|
119
83
|
exports.RUN_HOST_UNITS = ['cron', 'manual'];
|
|
120
|
-
/** The units a file pinned to `version` has in scope. */
|
|
121
|
-
function runHostUnits(version) {
|
|
122
|
-
return version >= 5 ? exports.RUN_HOST_UNITS : [];
|
|
123
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PACKAGE_VERSION = "0.12.0-rc.7";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PACKAGE_VERSION = void 0;
|
|
4
|
+
// The package's version, written here from package.json by
|
|
5
|
+
// scripts/build-packages.cjs (a source and its build sit at different depths
|
|
6
|
+
// beside package.json, so neither can require it by one relative path).
|
|
7
|
+
// __test__/language_version.unit.test.ts holds it equal to package.json.
|
|
8
|
+
exports.PACKAGE_VERSION = '0.12.0-rc.7';
|