@shapeshift-labs/frontier-lang-parser 0.3.8 → 0.3.9

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 CHANGED
@@ -20,7 +20,10 @@ The published Frontier package family is generated from one shared package catal
20
20
  - [`@shapeshift-labs/frontier-schema`](https://www.npmjs.com/package/@shapeshift-labs/frontier-schema): JSON Schema validation, Frontier profile generation, CloudEvent envelopes, and query/table schema helpers.
21
21
  - [`@shapeshift-labs/frontier-migrations`](https://www.npmjs.com/package/@shapeshift-labs/frontier-migrations): Boundary-first data migrations, import normalization, plugin/API version mapping, versioned envelopes, graph diagnostics, patch path rewrites, dry-run reports, and current-shape rehydration.
22
22
  - [`@shapeshift-labs/frontier-event-log`](https://www.npmjs.com/package/@shapeshift-labs/frontier-event-log): Bounded event logs, replay cursors, consumer acknowledgements, keyed compaction, checkpoints, and Frontier patch event records.
23
+ - [`@shapeshift-labs/frontier-run`](https://www.npmjs.com/package/@shapeshift-labs/frontier-run): Append-only distributed run graphs, causal event DAGs, evidence nodes, lanes, leases, refs, segments, dashboard projections, and admission decision records for Frontier agent work.
24
+ - [`@shapeshift-labs/frontier-lease`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lease): Runtime-neutral semantic, file, package, and repository lease claims with fencing tokens, expiry, conflict checks, apply validation, and replayable evidence for Frontier collaboration.
23
25
  - [`@shapeshift-labs/frontier-inspect`](https://www.npmjs.com/package/@shapeshift-labs/frontier-inspect): Cross-package inspection/evidence bundles, registry graph snapshots, feature/resource impact reports, timeline/event normalization, redaction, JSONL import/export, and AI-readable app feature maps.
26
+ - [`@shapeshift-labs/frontier-runtime-proof`](https://www.npmjs.com/package/@shapeshift-labs/frontier-runtime-proof): Runtime-neutral proof capsules, source-bound runtime telemetry, and admission evidence helpers for Frontier merge and review workflows.
24
27
  - [`@shapeshift-labs/frontier-scheduler`](https://www.npmjs.com/package/@shapeshift-labs/frontier-scheduler): Deterministic work scheduling, lanes, cancellation, backpressure, frame policies, replay snapshots, and work graphs.
25
28
  - [`@shapeshift-labs/frontier-logging`](https://www.npmjs.com/package/@shapeshift-labs/frontier-logging): Opt-in structured logging, browser telemetry, scheduled sinks, file sinks, exporters, benchmark traces, and Frontier patch/update summaries.
26
29
  - [`@shapeshift-labs/frontier-mutation`](https://www.npmjs.com/package/@shapeshift-labs/frontier-mutation): Explicit mutation and selector plans compiled to Frontier patches or CRDT operations.
@@ -35,15 +38,22 @@ The published Frontier package family is generated from one shared package catal
35
38
  - [`@shapeshift-labs/frontier-worker`](https://www.npmjs.com/package/@shapeshift-labs/frontier-worker): Serializable worker and edge task descriptors for Frontier apps, including queues, idempotency keys, retry and timeout policy, declared reads/writes/effects, snapshots, patch outputs, produced assets, execution records, logs, trace links, proof hashes, dedupe indexes, and registry graph output.
36
39
  - [`@shapeshift-labs/frontier-queue`](https://www.npmjs.com/package/@shapeshift-labs/frontier-queue): Serializable durable queue state, leases, retries, dedupe keys, patch-carrying jobs, dead-letter records, replay evidence, and queue inspection for Frontier apps.
37
40
  - [`@shapeshift-labs/frontier-swarm`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm): Hierarchical swarm plans, lanes, compute profiles, ownership policy, semantic ownership regions, task queues, event streams, run records, merge bundles, merge indexes, queue overlays, merge admission, coordinator dashboards, changed-path checks, and proof artifacts for Frontier agent work.
38
- - [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument compatibility, browser resource allocation, JSONL capture, verification commands, pid-backed stop, collect/apply workflows, merge indexes, queue overlays, merge bundles, normalized job evidence, coordinator query artifacts, and result artifacts.
41
+ - [`@shapeshift-labs/frontier-swarm-git`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-git): Node Git, workspace, patch, changed-path, write-fence, package-link repair, patch check, HEAD read, blob hash, and apply-ledger adapter for Frontier swarm runners.
42
+ - [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument compatibility, browser resource allocation, JSONL capture, verification commands, pid-backed stop, collect/apply workflows, merge indexes, queue overlays, merge bundles, normalized job evidence, coordinator query artifacts, result artifacts, and run-log sync adapters.
43
+ - [`@shapeshift-labs/frontier-loom-ui`](https://www.npmjs.com/package/@shapeshift-labs/frontier-loom-ui): Read-only Loom and Frontier operator dashboard for workspace-lifetime progress, active agents, queue state, evidence/admission status, run events, run-log sync projections, semantic leases, gate executions, git apply/workspace evidence, and coordinator steering intent files.
39
44
  - [`@shapeshift-labs/frontier-lang-kernel`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-kernel): Runtime-neutral semantic source graph, type/lattice/extern declarations, patch bundles, replay, hashing, evidence records, and merge-admission kernel for Frontier Lang.
40
45
  - [`@shapeshift-labs/frontier-lang-checker`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-checker): Checker and diagnostics for Frontier Lang semantic documents, including type symbols, effects, regions, lattice laws, CRDT metadata, and patch evidence.
41
46
  - [`@shapeshift-labs/frontier-lang-typescript`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-typescript): TypeScript projection adapter for Frontier Lang semantic documents, including type/entity/state/action/extern declarations and CRDT lattice descriptors.
42
47
  - [`@shapeshift-labs/frontier-lang-javascript`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-javascript): JavaScript projection adapter for Frontier Lang semantic documents, including ESM action stubs and schema/lattice descriptors.
48
+ - [`@shapeshift-labs/frontier-lang-jsx`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-jsx): Runtime-neutral JSX semantic merge evidence for Frontier Lang, including element identity, prop records, keyed children, spread props, source spans, and fail-closed renderer/runtime proof gaps.
49
+ - [`@shapeshift-labs/frontier-lang-svg`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-svg): Runtime-neutral SVG semantic merge evidence for Frontier Lang, including element identity, local id definitions, url/href reference graphs, source spans, and fail-closed paint/runtime proof gaps.
50
+ - [`@shapeshift-labs/frontier-lang-package`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-package): Runtime-neutral package manifest semantic merge evidence for Frontier Lang, including dependency, script, export/import, bin, workspace, package-manager, source-span, and fail-closed install/runtime proof gaps.
51
+ - [`@shapeshift-labs/frontier-lang-html`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-html): HTML semantic merge evidence and projection adapter for Frontier Lang semantic documents, including element tree identity, attributes, text/comment spans, source maps, and fail-closed browser/runtime proof gaps.
52
+ - [`@shapeshift-labs/frontier-lang-css`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-css): CSS semantic merge evidence and projection adapter for Frontier Lang semantic documents, including selector specificity, declaration/cascade keys, custom properties, `@property` and `@page` descriptor evidence, CSS Modules/ICSS export and composition evidence, source maps, and fail-closed browser cascade/render proof gaps.
43
53
  - [`@shapeshift-labs/frontier-lang-rust`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-rust): Rust projection adapter for Frontier Lang semantic documents, including structs, aliases, and action stubs.
44
54
  - [`@shapeshift-labs/frontier-lang-python`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-python): Python projection adapter for Frontier Lang semantic documents, including dataclasses, typed patch records, and action stubs.
45
55
  - [`@shapeshift-labs/frontier-lang-c`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-c): C header projection adapter for Frontier Lang semantic documents, including structs and action prototypes.
46
- - [`@shapeshift-labs/frontier-lang-compiler`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-compiler): Compiler facade for Frontier Lang source documents, including parse, check, hash, diagnostics, universal AST envelopes, proof/paradigm semantic summaries, projection to TypeScript, JavaScript, Rust, Python, and C, and native source-import adapters for semantic merge evidence.
56
+ - [`@shapeshift-labs/frontier-lang-compiler`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-compiler): Compiler facade for Frontier Lang source documents, including parse, check, hash, diagnostics, universal AST envelopes, proof/paradigm semantic summaries, projection to TypeScript, JavaScript, JSX, TSX, SVG, HTML, CSS, package manifests, Rust, Python, and C, and native source-import adapters for semantic merge evidence.
47
57
  - [`@shapeshift-labs/frontier-lang-swift`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-swift): Swift source-language importer package for Frontier Lang semantic documents, including package-level metadata, SwiftSyntax adapter helpers, native import results, and semantic sidecar generation for SwiftSyntax/SwiftParser-shaped syntax trees.
48
58
  - [`@shapeshift-labs/frontier-lang-kotlin`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-kotlin): Kotlin PSI source-language importer package for Frontier Lang semantic documents, including package-level metadata, Kotlin PSI adapter helpers, native import results, and semantic sidecar generation for Kotlin PSI/KtFile-shaped syntax trees.
49
59
  - [`@shapeshift-labs/frontier-lang-java`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-java): Java source-language importer package for Frontier Lang semantic documents, including package-level metadata, Java AST adapter helpers, native import results, and semantic sidecar generation for javac/JDT/JavaParser-shaped ASTs.
@@ -51,7 +61,7 @@ The published Frontier package family is generated from one shared package catal
51
61
  - [`@shapeshift-labs/frontier-lang-csharp`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-csharp): C# Roslyn source-language importer package for Frontier Lang semantic documents, including package-level metadata, Roslyn adapter helpers, native import results, and semantic sidecar generation for SyntaxTree/SyntaxNode-shaped ASTs.
52
62
  - [`@shapeshift-labs/frontier-lang-clang`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-clang): Clang AST source-language importer package for Frontier Lang semantic documents, including package-level metadata, Clang AST JSON adapter helpers, native import results, and semantic sidecar generation for C/C++ translation units.
53
63
  - [`@shapeshift-labs/frontier-lang-cli`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-cli): Command line interface for parsing, checking, hashing, emitting, native source import/projection, semantic slicing, and corpus roundtrip evidence for Frontier Lang projects.
54
- - [`@shapeshift-labs/frontier-lang`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang): Umbrella package for Frontier Lang kernel, parser, checker, compiler facade, universal AST helpers, projection adapters, and source-language importer adapters.
64
+ - [`@shapeshift-labs/frontier-lang`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang): Umbrella package for Frontier Lang kernel, parser, checker, compiler facade, universal AST helpers, projection adapters, HTML/CSS semantic merge evidence adapters, and source-language importer adapters.
55
65
  - [`@shapeshift-labs/frontier-kv`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv): Serializable in-memory key/value state for Frontier apps, including TTL, versioned compare-and-set, batched patch mutations, scans, watchers, snapshots, JSONL event evidence, and replay verification.
56
66
  - [`@shapeshift-labs/frontier-kv-locks`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv-locks): Lease-style lock records on top of Frontier KV, including acquire, renew, release, fencing tokens, expiration, owner evidence, and replayable lock events.
57
67
  - [`@shapeshift-labs/frontier-kv-rate-limit`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv-rate-limit): Patch-native rate limit buckets for Frontier KV, including fixed windows, sliding windows, token buckets, deterministic refill, consume evidence, and reset records.
@@ -96,6 +106,7 @@ The published Frontier package family is generated from one shared package catal
96
106
  - [`@shapeshift-labs/frontier-realtime-server`](https://www.npmjs.com/package/@shapeshift-labs/frontier-realtime-server): Authoritative realtime room, tick, command validation, rate-limit, session, and snapshot-history runtime.
97
107
  - [`@shapeshift-labs/frontier-realtime-websocket`](https://www.npmjs.com/package/@shapeshift-labs/frontier-realtime-websocket): WebSocket client, wire, and Node room-server transport for Frontier realtime.
98
108
  - [`@shapeshift-labs/frontier-game`](https://www.npmjs.com/package/@shapeshift-labs/frontier-game): Game-facing entity, component, player, room, ownership, spatial interest, rollback, physics, and replication helpers above realtime.
109
+ - [`@shapeshift-labs/loom`](https://www.npmjs.com/package/@shapeshift-labs/loom): Repo-level semantic collaboration CLI for .loom workspaces, including init, scan, status, graph snapshots, projection plans, Frontier Lang delegation, Frontier Swarm delegation, run-log sync command delegation, and Frontier Framework delegation.
99
110
 
100
111
  Package source repositories:
101
112
 
@@ -112,7 +123,10 @@ Package source repositories:
112
123
  - [`siliconjungle/-shapeshift-labs-frontier-schema`](https://github.com/siliconjungle/-shapeshift-labs-frontier-schema)
113
124
  - [`siliconjungle/-shapeshift-labs-frontier-migrations`](https://github.com/siliconjungle/-shapeshift-labs-frontier-migrations)
114
125
  - [`siliconjungle/-shapeshift-labs-frontier-event-log`](https://github.com/siliconjungle/-shapeshift-labs-frontier-event-log)
126
+ - [`siliconjungle/-shapeshift-labs-frontier-run`](https://github.com/siliconjungle/-shapeshift-labs-frontier-run)
127
+ - [`siliconjungle/-shapeshift-labs-frontier-lease`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lease)
115
128
  - [`siliconjungle/-shapeshift-labs-frontier-inspect`](https://github.com/siliconjungle/-shapeshift-labs-frontier-inspect)
129
+ - [`siliconjungle/-shapeshift-labs-frontier-runtime-proof`](https://github.com/siliconjungle/-shapeshift-labs-frontier-runtime-proof)
116
130
  - [`siliconjungle/-shapeshift-labs-frontier-scheduler`](https://github.com/siliconjungle/-shapeshift-labs-frontier-scheduler)
117
131
  - [`siliconjungle/-shapeshift-labs-frontier-logging`](https://github.com/siliconjungle/-shapeshift-labs-frontier-logging)
118
132
  - [`siliconjungle/-shapeshift-labs-frontier-mutation`](https://github.com/siliconjungle/-shapeshift-labs-frontier-mutation)
@@ -127,12 +141,19 @@ Package source repositories:
127
141
  - [`siliconjungle/-shapeshift-labs-frontier-worker`](https://github.com/siliconjungle/-shapeshift-labs-frontier-worker)
128
142
  - [`siliconjungle/-shapeshift-labs-frontier-queue`](https://github.com/siliconjungle/-shapeshift-labs-frontier-queue)
129
143
  - [`siliconjungle/-shapeshift-labs-frontier-swarm`](https://github.com/siliconjungle/-shapeshift-labs-frontier-swarm)
144
+ - [`siliconjungle/-shapeshift-labs-frontier-swarm-git`](https://github.com/siliconjungle/-shapeshift-labs-frontier-swarm-git)
130
145
  - [`siliconjungle/-shapeshift-labs-frontier-swarm-codex`](https://github.com/siliconjungle/-shapeshift-labs-frontier-swarm-codex)
146
+ - [`siliconjungle/frontier-loom-ui`](https://github.com/siliconjungle/frontier-loom-ui)
131
147
  - [`siliconjungle/-shapeshift-labs-frontier-lang-kernel`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-kernel)
132
148
  - [`siliconjungle/-shapeshift-labs-frontier-lang-parser`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-parser)
133
149
  - [`siliconjungle/-shapeshift-labs-frontier-lang-checker`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-checker)
134
150
  - [`siliconjungle/-shapeshift-labs-frontier-lang-typescript`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-typescript)
135
151
  - [`siliconjungle/-shapeshift-labs-frontier-lang-javascript`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-javascript)
152
+ - [`siliconjungle/-shapeshift-labs-frontier-lang-jsx`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-jsx)
153
+ - [`siliconjungle/-shapeshift-labs-frontier-lang-svg`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-svg)
154
+ - [`siliconjungle/-shapeshift-labs-frontier-lang-package`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-package)
155
+ - [`siliconjungle/-shapeshift-labs-frontier-lang-html`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-html)
156
+ - [`siliconjungle/-shapeshift-labs-frontier-lang-css`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-css)
136
157
  - [`siliconjungle/-shapeshift-labs-frontier-lang-rust`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-rust)
137
158
  - [`siliconjungle/-shapeshift-labs-frontier-lang-python`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-python)
138
159
  - [`siliconjungle/-shapeshift-labs-frontier-lang-c`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-c)
@@ -189,6 +210,7 @@ Package source repositories:
189
210
  - [`siliconjungle/-shapeshift-labs-frontier-realtime-server`](https://github.com/siliconjungle/-shapeshift-labs-frontier-realtime-server)
190
211
  - [`siliconjungle/-shapeshift-labs-frontier-realtime-websocket`](https://github.com/siliconjungle/-shapeshift-labs-frontier-realtime-websocket)
191
212
  - [`siliconjungle/-shapeshift-labs-frontier-game`](https://github.com/siliconjungle/-shapeshift-labs-frontier-game)
213
+ - [`siliconjungle/-shapeshift-labs-loom`](https://github.com/siliconjungle/-shapeshift-labs-loom)
192
214
 
193
215
  ## Install
194
216
 
package/dist/index.js CHANGED
@@ -6,20 +6,26 @@ import {
6
6
  entityNode,
7
7
  externNode,
8
8
  latticeNode,
9
+ migrationNode,
9
10
  nativeSourceNode,
10
11
  stateNode,
11
12
  targetNode,
12
13
  typeNode
13
14
  } from '@shapeshift-labs/frontier-lang-kernel';
15
+ import { parseProofBlock } from './proof.js';
16
+ import { parseViewBlock } from './view.js';
14
17
 
15
18
  export function parseFrontierSource(source, options = {}) {
16
19
  const nodes = [];
20
+ const proofBlocks = [];
17
21
  const documentId = options.id ?? readId(source) ?? 'mod_frontier';
18
22
  const documentName = options.name ?? readName(source) ?? 'FrontierModule';
19
23
  for (const block of readBlocks(source)) {
20
24
  if (block.kind === 'entity') nodes.push(parseEntity(block));
21
25
  if (block.kind === 'state') nodes.push(parseState(block));
22
26
  if (block.kind === 'action') nodes.push(parseAction(block));
27
+ if (block.kind === 'view') nodes.push(parseViewBlock(block));
28
+ if (block.kind === 'migration') nodes.push(parseMigration(block));
23
29
  if (block.kind === 'capability') nodes.push(parseCapability(block));
24
30
  if (block.kind === 'effect') nodes.push(parseEffect(block));
25
31
  if (block.kind === 'type') nodes.push(parseType(block));
@@ -27,19 +33,18 @@ export function parseFrontierSource(source, options = {}) {
27
33
  if (block.kind === 'lattice') nodes.push(parseLattice(block));
28
34
  if (block.kind === 'nativeSource') nodes.push(parseNativeSource(block));
29
35
  if (block.kind === 'target') nodes.push(parseTarget(block));
36
+ if (block.kind === 'proof') proofBlocks.push(parseProofBlock(block));
30
37
  }
31
- return createDocument({ id: documentId, name: documentName, nodes });
38
+ return createDocument({ id: documentId, name: documentName, nodes, ...(proofBlocks.length ? { metadata: { proof: mergeProofBlocks(proofBlocks) } } : {}) });
32
39
  }
33
40
 
34
- export function parseFrontierFile(name, source) {
35
- return parseFrontierSource(source, { name: name.replace(/\.frontier$/, '') });
36
- }
41
+ export function parseFrontierFile(name, source) { return parseFrontierSource(source, { name: name.replace(/\.frontier$/, '') }); }
37
42
 
38
43
  function readName(source) { return /module\s+([A-Za-z_$][\w$]*)/.exec(source)?.[1]; }
39
44
  function readId(source) { return /module\s+[A-Za-z_$][\w$]*\s+@id\(\s*["']([^"']+)["']\s*\)/.exec(source)?.[1]; }
40
45
  function readBlocks(source) {
41
46
  const blocks = [];
42
- const header = /\b(entity|state|action|capability|effect|type|extern|lattice|nativeSource|target)\s+([^{}]+)\{/g;
47
+ const header = /\b(entity|state|action|view|migration|capability|effect|type|extern|lattice|nativeSource|target|proof)\s+([^{}]+)\{/g;
43
48
  let match;
44
49
  while ((match = header.exec(source))) {
45
50
  let depth = 1; let index = header.lastIndex;
@@ -49,6 +54,15 @@ function readBlocks(source) {
49
54
  }
50
55
  return blocks;
51
56
  }
57
+ const PROOF_GROUPS = ['contracts', 'refinements', 'invariants', 'termination', 'temporal', 'obligations', 'artifacts', 'assumptions'];
58
+ function mergeProofBlocks(blocks) {
59
+ const proof = {
60
+ id: blocks.length === 1 ? blocks[0].id : 'proof:source',
61
+ metadata: { authoredProofBlockIds: blocks.map((block) => block.id) }
62
+ };
63
+ for (const group of PROOF_GROUPS) proof[group] = blocks.flatMap((block) => block[group] ?? []);
64
+ return proof;
65
+ }
52
66
  function idFrom(header, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(header)?.[1] ?? fallback; }
53
67
  function nameFrom(header) { return /^([A-Za-z_$][\w$]*)/.exec(header)?.[1] ?? 'Unnamed'; }
54
68
  function parseEntity(block) {
@@ -97,6 +111,10 @@ function parseAction(block) {
97
111
  uses: readList('uses', block.body)
98
112
  });
99
113
  }
114
+ function parseMigration(block) {
115
+ const name = nameFrom(block.header);
116
+ return migrationNode({ id: idFrom(block.header, `migration_${name}`), name, fromVersion: readWord('fromVersion', block.body) ?? readWord('from', block.body) ?? 'unknown', toVersion: readWord('toVersion', block.body) ?? readWord('to', block.body) ?? 'unknown', changes: readChangeRecords(block.body), invariants: readList('invariants', block.body) });
117
+ }
100
118
  function parseEffect(block) {
101
119
  const name = nameFrom(block.header);
102
120
  return effectNode({
@@ -246,6 +264,16 @@ function readUnsupportedTargets(body) {
246
264
  }
247
265
  return unsupported.length ? unsupported : undefined;
248
266
  }
267
+ function readChangeRecords(body) {
268
+ const changes = [];
269
+ const re = /^\s*change\s+([A-Za-z][\w-]*)(?:\s+([^\n]+))?/gm;
270
+ let match;
271
+ while ((match = re.exec(body))) {
272
+ const statement = match[2]?.trim();
273
+ changes.push({ id: `change_${changes.length}`, kind: match[1], ...(statement ? { statement, target: statement.split(/\s+/)[0] } : {}) });
274
+ }
275
+ return changes;
276
+ }
249
277
  function parseMerge(text) {
250
278
  const kind = /merge\s+([A-Za-z][\w-]*)/.exec(text)?.[1];
251
279
  if (!kind) return undefined;
package/dist/proof.js ADDED
@@ -0,0 +1,120 @@
1
+ const CONTRACT_GROUPS = {
2
+ contract: 'contracts',
3
+ refinement: 'refinements',
4
+ invariant: 'invariants',
5
+ termination: 'termination',
6
+ temporal: 'temporal'
7
+ };
8
+
9
+ export function parseProofBlock(block) {
10
+ const name = nameFrom(block.header);
11
+ const proof = {
12
+ id: idFrom(block.header, `proof_${name}`),
13
+ contracts: [],
14
+ refinements: [],
15
+ invariants: [],
16
+ termination: [],
17
+ temporal: [],
18
+ obligations: [],
19
+ artifacts: [],
20
+ assumptions: [],
21
+ metadata: { name }
22
+ };
23
+ for (const rawLine of block.body.split('\n')) {
24
+ const line = rawLine.trim();
25
+ if (!line || line.startsWith('#')) continue;
26
+ const match = /^(contract|refinement|invariant|termination|temporal|obligation|artifact|assumption)\s+([A-Za-z_$][\w$-]*)(.*)$/.exec(line);
27
+ if (!match) continue;
28
+ const [, section, recordName, rest] = match;
29
+ const group = CONTRACT_GROUPS[section];
30
+ if (group) proof[group].push(parseProofContract(section, recordName, rest));
31
+ if (section === 'obligation') proof.obligations.push(parseProofObligation(recordName, rest));
32
+ if (section === 'artifact') proof.artifacts.push(parseProofArtifact(recordName, rest));
33
+ if (section === 'assumption') proof.assumptions.push(parseProofAssumption(recordName, rest));
34
+ }
35
+ return omitEmptyArrays(proof);
36
+ }
37
+
38
+ function parseProofContract(section, name, text) {
39
+ return cleanRecord({
40
+ id: idFrom(text, `proof_${section}_${name}`),
41
+ kind: readInlineWord('kind', text) ?? section,
42
+ subjectKind: readInlineWord('subjectKind', text),
43
+ subjectId: readInlineWord('subject', text) ?? readInlineWord('subjectId', text),
44
+ expression: readInlineQuoted('expression', text),
45
+ statement: readInlineQuoted('statement', text),
46
+ language: readInlineWord('language', text),
47
+ sourceMapId: readInlineWord('sourceMap', text) ?? readInlineWord('sourceMapId', text),
48
+ sourceMapMappingId: readInlineWord('sourceMapMapping', text) ?? readInlineWord('sourceMapMappingId', text),
49
+ evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
50
+ lossIds: readInlineList(text, 'loss', 'lossIds'),
51
+ metadata: { name }
52
+ });
53
+ }
54
+
55
+ function parseProofObligation(name, text) {
56
+ return cleanRecord({
57
+ id: idFrom(text, `proof_obligation_${name}`),
58
+ kind: readInlineWord('kind', text),
59
+ status: readInlineWord('status', text),
60
+ subjectKind: readInlineWord('subjectKind', text),
61
+ subjectId: readInlineWord('subject', text) ?? readInlineWord('subjectId', text),
62
+ expression: readInlineQuoted('expression', text),
63
+ statement: readInlineQuoted('statement', text),
64
+ contractIds: readInlineList(text, 'contract', 'contracts', 'contractIds'),
65
+ assumptionIds: readInlineList(text, 'assumption', 'assumptions', 'assumptionIds'),
66
+ artifactIds: readInlineList(text, 'artifact', 'artifacts', 'artifactIds'),
67
+ evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
68
+ lossIds: readInlineList(text, 'loss', 'lossIds'),
69
+ solver: readInlineWord('solver', text),
70
+ staleAgainstHash: readInlineWord('staleAgainstHash', text),
71
+ metadata: { name }
72
+ });
73
+ }
74
+
75
+ function parseProofArtifact(name, text) {
76
+ return cleanRecord({
77
+ id: idFrom(text, `proof_artifact_${name}`),
78
+ kind: readInlineWord('kind', text),
79
+ status: readInlineWord('status', text),
80
+ path: readInlineWord('path', text),
81
+ hash: readInlineWord('hash', text),
82
+ command: readInlineQuoted('command', text),
83
+ prover: readInlineWord('prover', text),
84
+ obligationIds: readInlineList(text, 'obligation', 'obligations', 'obligationIds'),
85
+ assumptionIds: readInlineList(text, 'assumption', 'assumptions', 'assumptionIds'),
86
+ evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
87
+ summary: readInlineQuoted('summary', text),
88
+ metadata: { name }
89
+ });
90
+ }
91
+
92
+ function parseProofAssumption(name, text) {
93
+ return cleanRecord({
94
+ id: idFrom(text, `proof_assumption_${name}`),
95
+ scope: readInlineWord('scope', text),
96
+ subjectKind: readInlineWord('subjectKind', text),
97
+ subjectId: readInlineWord('subject', text) ?? readInlineWord('subjectId', text),
98
+ description: readInlineQuoted('description', text),
99
+ evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
100
+ metadata: { name }
101
+ });
102
+ }
103
+
104
+ function idFrom(text, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(text)?.[1] ?? fallback; }
105
+ function nameFrom(header) { return /^([A-Za-z_$][\w$]*)/.exec(header)?.[1] ?? 'Proof'; }
106
+ function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
107
+ function readInlineQuoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
108
+ function readInlineList(text, ...labels) {
109
+ for (const label of labels) {
110
+ const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(text)?.[1]?.trim();
111
+ if (value) return value.split(/[|,]/).map((item) => item.trim()).filter(Boolean);
112
+ }
113
+ return undefined;
114
+ }
115
+ function cleanRecord(record) {
116
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0)));
117
+ }
118
+ function omitEmptyArrays(record) {
119
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => !Array.isArray(value) || value.length > 0));
120
+ }
package/dist/view.js ADDED
@@ -0,0 +1,103 @@
1
+ import { viewNode } from '@shapeshift-labs/frontier-lang-kernel';
2
+
3
+ export function parseViewBlock(block) {
4
+ const name = nameFrom(block.header);
5
+ const topLevelBody = stripNestedBlocks('render', block.body);
6
+ const props = readViewProps(topLevelBody);
7
+ const events = readViewEvents(topLevelBody);
8
+ const renders = readRenderNodes(block.body);
9
+ return viewNode({
10
+ id: idFrom(block.header, `view_${name}`),
11
+ name,
12
+ reads: readList('reads', topLevelBody),
13
+ dispatches: readList('dispatches', topLevelBody) ?? readList('dispatch', topLevelBody),
14
+ props: props.length ? props : undefined,
15
+ events: events.length ? events : undefined,
16
+ renders: renders.length ? renders : undefined
17
+ });
18
+ }
19
+
20
+ function readViewProps(body) {
21
+ const props = [];
22
+ const re = /^\s*prop\s+([A-Za-z_$][\w$.-]*)(?:\s+@id\(\s*["']([^"']+)["']\s*\))?\s*:\s*([^\n]+)$/gm;
23
+ let match;
24
+ while ((match = re.exec(body))) props.push({ id: match[2] ?? `view_prop_${match[1]}`, name: match[1], type: parseTypeExpression(match[3].replace(/\s+optional\s*$/, '').trim()), optional: /\soptional\s*$/.test(match[3]) || undefined });
25
+ return props;
26
+ }
27
+
28
+ function readViewEvents(body) {
29
+ const events = [];
30
+ const re = /^\s*event\s+([A-Za-z_$][\w$.-]*)(?:\s+@id\(\s*["']([^"']+)["']\s*\))?([^\n]*)$/gm;
31
+ let match;
32
+ while ((match = re.exec(body))) events.push({ id: match[2] ?? `view_event_${match[1]}`, name: match[1], action: readInlineWord('action', match[3]), input: parseOptionalTypeExpression(readInlineWord('input', match[3])) });
33
+ return events;
34
+ }
35
+
36
+ function readRenderNodes(body) {
37
+ return readNestedBlocks('render', body).map((block) => {
38
+ const tagName = nameFrom(block.header);
39
+ const props = readRenderProps(block.body);
40
+ const events = readRenderEvents(block.body);
41
+ return {
42
+ id: idFrom(block.header, `render_${tagName}`),
43
+ kind: readInlineWord('kind', block.header) ?? 'element',
44
+ tagName,
45
+ identityKey: readLine('identity', block.body) ?? readLine('key', block.body),
46
+ text: readQuotedLine('text', block.body),
47
+ props: props.length ? props : undefined,
48
+ events: events.length ? events : undefined
49
+ };
50
+ });
51
+ }
52
+
53
+ function readRenderProps(body) {
54
+ const props = [];
55
+ const re = /^\s*prop\s+([A-Za-z_$][\w$.-]*)\s+([^\n]+)$/gm;
56
+ let match;
57
+ while ((match = re.exec(body))) props.push({ name: match[1], ...readRenderValue(match[2]) });
58
+ return props;
59
+ }
60
+
61
+ function readRenderEvents(body) {
62
+ const events = [];
63
+ const re = /^\s*on\s+([A-Za-z_$][\w$.-]*)\s+([A-Za-z_$][\w$.-]*)/gm;
64
+ let match;
65
+ while ((match = re.exec(body))) events.push({ name: match[1], action: match[2] });
66
+ return events;
67
+ }
68
+
69
+ function readNestedBlocks(kind, source) {
70
+ const blocks = [];
71
+ const header = new RegExp('\\b' + kind + '\\s+([^{}]+)\\{', 'g');
72
+ let match;
73
+ while ((match = header.exec(source))) {
74
+ let depth = 1; let index = header.lastIndex;
75
+ while (index < source.length && depth > 0) { const ch = source[index++]; if (ch === '{') depth++; if (ch === '}') depth--; }
76
+ blocks.push({ kind, header: match[1].trim(), body: source.slice(header.lastIndex, index - 1), start: match.index, end: index });
77
+ header.lastIndex = index;
78
+ }
79
+ return blocks;
80
+ }
81
+
82
+ function stripNestedBlocks(kind, source) {
83
+ let text = source;
84
+ for (const block of readNestedBlocks(kind, source).reverse()) text = text.slice(0, block.start) + text.slice(block.end);
85
+ return text;
86
+ }
87
+
88
+ function idFrom(header, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(header)?.[1] ?? fallback; }
89
+ function nameFrom(header) { return /^([A-Za-z_$][\w$]*)/.exec(header)?.[1] ?? 'Unnamed'; }
90
+ function readList(label, body) { const line = new RegExp('^\\s*' + label + '\\s+([^\\n]+)', 'm').exec(body)?.[1]; return line ? line.split(',').map((item) => item.trim()).filter(Boolean) : undefined; }
91
+ function readLine(label, body) { return new RegExp('^\\s*' + label + '\\s+([^\\n]+)', 'm').exec(body)?.[1]?.trim(); }
92
+ function readQuotedLine(label, body) { return new RegExp(`^\\s*${label}\\s+["']([^"']+)["']`, 'm').exec(body)?.[1]; }
93
+ function readInlineWord(label, text = '') { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
94
+ function readRenderValue(value) { const quoted = /^["']([^"']+)["']$/.exec(value.trim()); return quoted ? { value: quoted[1] } : { expression: value.trim() }; }
95
+ function parseOptionalTypeExpression(value) { return value ? parseTypeExpression(value.trim()) : undefined; }
96
+ function parseTypeExpression(value) {
97
+ const text = value.trim();
98
+ if (/^Set<.+>$/.test(text)) return { kind: 'set', item: parseTypeExpression(text.slice(4, -1)) };
99
+ if (/^List<.+>$/.test(text)) return { kind: 'list', item: parseTypeExpression(text.slice(5, -1)) };
100
+ const map = /^Map<(.+),\s*(.+)>$/.exec(text);
101
+ if (map) return { kind: 'map', key: parseTypeExpression(map[1]), value: parseTypeExpression(map[2]) };
102
+ return text;
103
+ }
@@ -2,4 +2,25 @@ module TodoApp @id("mod_todo") {
2
2
  entity Todo @id("ent_todo") {
3
3
  title @id("field_title"): Text { merge conflict }
4
4
  }
5
+ state TodoDb @id("state_todo") {
6
+ todos @id("collection_todos"): Map<TodoId, Todo> { merge byKey law commutative }
7
+ }
8
+ view TodoList @id("view_todo_list") {
9
+ reads TodoDb.todos
10
+ dispatches action_add
11
+ prop disabled @id("view_prop_disabled"): Boolean
12
+ event save @id("view_event_save") action action_add input TodoInput
13
+ render Button @id("render_save_button") {
14
+ identity save
15
+ text "Save"
16
+ prop disabled disabled
17
+ on press save
18
+ }
19
+ }
20
+ migration TodoV1ToV2 @id("migration_todo_v1_v2") {
21
+ from 1
22
+ to 2
23
+ change addField Todo.title
24
+ invariants title_present
25
+ }
5
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-parser",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "Parser for the first Frontier Lang .frontier syntax slice.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -44,7 +44,7 @@
44
44
  "license": "MIT",
45
45
  "repository": {
46
46
  "type": "git",
47
- "url": "git+https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-parser.git"
47
+ "url": "git+ssh://git@github.com/siliconjungle/-shapeshift-labs-frontier-lang-parser.git"
48
48
  },
49
49
  "bugs": {
50
50
  "url": "https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-parser/issues"