@jigs.design/compiler 0.2.0 → 0.3.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 CHANGED
@@ -1,10 +1,10 @@
1
1
  # @jigs.design/compiler
2
2
 
3
- Today's Jigs compiler: the parser, the checker against a catalog, the code generator, recipe libraries, and the SEARCH/REPLACE edit helpers. `@jigs.design/server` and `@jigs.design/prompt` use it. You import it for tooling, not to run a session.
3
+ Today's Jigs compiler: the parser, the checker against a catalog, the code generator, jig libraries, and the SEARCH/REPLACE edit helpers. `@jigs.design/server` and `@jigs.design/prompt` use it. You import it for tooling, not to run a session.
4
4
 
5
5
  Its diagnostics are the `Diagnostic` type from `@jigs.design/protocol`, the shape the server sends; it imports that package's types and nothing else from it. It parses embedded code with [acorn](https://github.com/acornjs/acorn) in strict mode, the mode programs run in, and checks names and the JavaScript subset. It has no built-in catalog. Every caller passes one, and its prop kinds are boolean, enum, handler, number, rows and string.
6
6
 
7
- The [language RFC](../../docs/language-v2/rfc.md) plans its next changes. It evolves in place, behind the same server API.
7
+ It evolves in place, behind the same server API. The [language plan's record](../../.agent-docs/notes/language-v2-2026-10.md) says what each phase changed, and `.agent-docs/deferred.md` what is set aside.
8
8
 
9
9
  ## Exports
10
10
 
@@ -12,18 +12,18 @@ The [language RFC](../../docs/language-v2/rfc.md) plans its next changes. It evo
12
12
  | ---------------------------------------------------------- | ---------------------------------------------------------------- |
13
13
  | `parseJigs` | Source to a document tree. Tolerates a prefix cut off mid-stream |
14
14
  | `compileJigs` | Checks a document against a catalog and generates its program |
15
- | `compileLibrary` | Compiles recipes into a library a document can use |
16
- | `recipeSignature` | A recipe's props and slot, as the prompt lists them |
15
+ | `compileLibrary` | Compiles jigs into a library a document can use |
16
+ | `jigSignature` | A jig's props and slot, as the prompt lists them |
17
17
  | `isEditReply`, `parseEdits`, `applyEdits`, `SEARCH_MARKER` | Recognise and apply a reply made of SEARCH/REPLACE edits |
18
18
  | `CompileCatalog`, `ComponentSpec`, `PropSpec` | What the compiler checks against |
19
19
 
20
20
  ## Source
21
21
 
22
22
  - `src/parse.ts`, `src/ast.ts`: the parser and its tree.
23
- - `src/compile.ts`: checking, recipes and diagnostics.
23
+ - `src/compile.ts`: checking, jig libraries and diagnostics.
24
24
  - `src/script.ts`, `src/check-code.ts`: embedded code read with acorn, and the checks on it.
25
25
  - `src/suggest.ts`: the nearest name, for "did you mean".
26
26
  - `src/codegen.ts`: the JavaScript the sandbox runs.
27
27
  - `src/patch.ts`: SEARCH/REPLACE edits.
28
- - `src/spec.ts`, `src/signature.ts`: catalog specs and recipe signatures.
28
+ - `src/spec.ts`, `src/signature.ts`: catalog specs and jig signatures.
29
29
  - `src/test-catalog.ts`: the catalog the tests run against.
package/dist/compile.d.ts CHANGED
@@ -110,7 +110,7 @@ export interface CompiledDefine {
110
110
  name: string;
111
111
  origin: "doc" | "library";
112
112
  /**
113
- * The procedure calls in a library recipe's source, by its lines. Empty
113
+ * The procedure calls in a library jig's source, by its lines. Empty
114
114
  * for a document's own define: those are on the document's result.
115
115
  */
116
116
  procedures: ReadonlyArray<ProcedureUse>;
@@ -130,28 +130,28 @@ export interface Program {
130
130
  tree: Array<RenderNode>;
131
131
  }
132
132
  /** A reusable component written in Jigs: source with exactly one `<define>`. */
133
- export interface Recipe {
133
+ export interface Jig {
134
134
  name: string;
135
135
  source: string;
136
136
  }
137
- /** Recipes compiled against one catalog, ready to use in documents. */
137
+ /** Jigs compiled against one catalog, ready to use in documents. */
138
138
  export type Library = ReadonlyMap<string, CompiledDefine>;
139
139
  export interface CompileOptions {
140
140
  /** The components a document may use. */
141
141
  catalog: CompileCatalog;
142
- /** Recipes in scope, from `compileLibrary` with the same catalog. */
142
+ /** Jigs in scope, from `compileLibrary` with the same catalog. */
143
143
  library?: Library;
144
144
  }
145
145
  export interface CompileResult {
146
146
  defines: ReadonlyArray<CompiledDefine>;
147
147
  diagnostics: Array<Diagnostic$1>;
148
- /** The recipes this document was compiled against. */
148
+ /** The jigs this document was compiled against. */
149
149
  library: ReadonlyMap<string, CompiledDefine>;
150
150
  output: ProgramOutput;
151
151
  /**
152
152
  * Every `useQuery`, `useMutation` and `useAction` call in the parsed
153
153
  * code of the document and its defines, in line order: nothing in
154
- * prose or in string literals. Recipes' calls are on the library's
154
+ * prose or in string literals. Library jigs' calls are on the library's
155
155
  * defines.
156
156
  */
157
157
  procedures: ReadonlyArray<ProcedureUse>;
@@ -165,11 +165,11 @@ export interface CompileResult {
165
165
  source: string;
166
166
  }
167
167
  /**
168
- * Compiles `recipes` against `catalog`, in order: a recipe may use the ones
169
- * before it. Throws when a recipe has any diagnostic. Cached per catalog and
170
- * recipe list.
168
+ * Compiles `jigs` against `catalog`, in order: a jig may use the ones
169
+ * before it. Throws when a jig has any diagnostic. Cached per catalog and
170
+ * jig list.
171
171
  */
172
- export declare function compileLibrary(recipes: ReadonlyArray<Recipe>, catalog: CompileCatalog): Library;
172
+ export declare function compileLibrary(jigs: ReadonlyArray<Jig>, catalog: CompileCatalog): Library;
173
173
  /**
174
174
  * Compiles a document. An error that carries a fix is applied rather than
175
175
  * sent to the model: the fixed source is compiled again, and when it has
package/dist/compile.js CHANGED
@@ -58,7 +58,7 @@ function hookMisuse(code, kind, block) {
58
58
  return null;
59
59
  }
60
60
  const NO_LIBRARY = /* @__PURE__ */ new Map();
61
- /** Libraries by catalog, then by recipe list. */
61
+ /** Libraries by catalog, then by jig list. */
62
62
  const libraryCache = /* @__PURE__ */ new WeakMap();
63
63
  function propSpec(spec, name) {
64
64
  const props = spec.props;
@@ -738,7 +738,7 @@ function emittedDefines(tree, docDefines, available) {
738
738
  }
739
739
  /**
740
740
  * Static call sites in the document tree and in document-local define bodies.
741
- * A tag inside a library recipe is not counted again.
741
+ * A tag inside a library jig is not counted again.
742
742
  */
743
743
  function countUses(tree, docDefines) {
744
744
  const counts = /* @__PURE__ */ new Map();
@@ -865,14 +865,14 @@ function compileDocument(source, library, components) {
865
865
  }
866
866
  function buildLibrary(list, components) {
867
867
  const built = /* @__PURE__ */ new Map();
868
- for (const recipe of list) {
869
- if (built.has(recipe.name)) throw new Error(`Recipe name "${recipe.name}" is duplicated`);
870
- const result = compileDocument(recipe.source, built, components);
868
+ for (const jig of list) {
869
+ if (built.has(jig.name)) throw new Error(`Jig name "${jig.name}" is duplicated`);
870
+ const result = compileDocument(jig.source, built, components);
871
871
  const problem = result.findings[0];
872
- if (problem !== void 0) throw new Error(`Recipe "${recipe.name}" failed to compile: line ${problem.line}: ${problem.message}`);
872
+ if (problem !== void 0) throw new Error(`Jig "${jig.name}" failed to compile: line ${problem.line}: ${problem.message}`);
873
873
  const def = result.defines[0];
874
- if (result.defines.length !== 1 || def === void 0) throw new Error(`Recipe "${recipe.name}" must contain exactly one <define>`);
875
- if (def.name !== recipe.name) throw new Error(`Recipe "${recipe.name}" defines <${def.name}> instead`);
874
+ if (result.defines.length !== 1 || def === void 0) throw new Error(`Jig "${jig.name}" must contain exactly one <define>`);
875
+ if (def.name !== jig.name) throw new Error(`Jig "${jig.name}" defines <${def.name}> instead`);
876
876
  built.set(def.name, {
877
877
  ...def,
878
878
  origin: "library",
@@ -882,17 +882,17 @@ function buildLibrary(list, components) {
882
882
  return built;
883
883
  }
884
884
  /**
885
- * Compiles `recipes` against `catalog`, in order: a recipe may use the ones
886
- * before it. Throws when a recipe has any diagnostic. Cached per catalog and
887
- * recipe list.
885
+ * Compiles `jigs` against `catalog`, in order: a jig may use the ones
886
+ * before it. Throws when a jig has any diagnostic. Cached per catalog and
887
+ * jig list.
888
888
  */
889
- function compileLibrary(recipes, catalog) {
890
- const byRecipes = libraryCache.get(catalog) ?? /* @__PURE__ */ new WeakMap();
891
- libraryCache.set(catalog, byRecipes);
892
- const existing = byRecipes.get(recipes);
889
+ function compileLibrary(jigs, catalog) {
890
+ const byJigs = libraryCache.get(catalog) ?? /* @__PURE__ */ new WeakMap();
891
+ libraryCache.set(catalog, byJigs);
892
+ const existing = byJigs.get(jigs);
893
893
  if (existing !== void 0) return existing;
894
- const built = buildLibrary(recipes, catalog);
895
- byRecipes.set(recipes, built);
894
+ const built = buildLibrary(jigs, catalog);
895
+ byJigs.set(jigs, built);
896
896
  return built;
897
897
  }
898
898
  /** `source` with the fixes' edits applied. */
package/dist/index.d.ts CHANGED
@@ -2,11 +2,11 @@ import { columnAt, lineAt, rangeIn, spanIn } from "./offsets.js";
2
2
  import { JigsNode, Statement } from "./ast.js";
3
3
  import { CompileCatalog, ComponentSpec, PropSpec } from "./spec.js";
4
4
  import { ProgramOutput } from "./codegen.js";
5
- import { CompileOptions, CompileResult, CompiledDefine, Diagnostic, Library, Program, Recipe, RenderNode, compileJigs, compileLibrary } from "./compile.js";
5
+ import { CompileOptions, CompileResult, CompiledDefine, Diagnostic, Jig, Library, Program, RenderNode, compileJigs, compileLibrary } from "./compile.js";
6
6
  import { DataRead, ELEMENT, ProcedureUse } from "./check-code.js";
7
7
  import { Hoisted, hoistDeclarations } from "./hoist.js";
8
8
  import { parseJigs } from "./parse.js";
9
9
  import { nearest } from "./suggest.js";
10
- import { recipeSignature } from "./signature.js";
10
+ import { jigSignature } from "./signature.js";
11
11
  import { Edit, EditFailure, EditFailureReason, SEARCH_MARKER, applyEdits, editBreakage, isEditReply, parseEdits } from "./patch.js";
12
- export { type CompileCatalog, type CompileOptions, type CompileResult, type CompiledDefine, type ComponentSpec, type DataRead, type Diagnostic, ELEMENT, type Edit, type EditFailure, type EditFailureReason, type Hoisted, type JigsNode, type Library, type ProcedureUse, type Program, type ProgramOutput, type PropSpec, type Recipe, type RenderNode, SEARCH_MARKER, type Statement, applyEdits, columnAt, compileJigs, compileLibrary, editBreakage, hoistDeclarations, isEditReply, lineAt, nearest, parseEdits, parseJigs, rangeIn, recipeSignature, spanIn };
12
+ export { type CompileCatalog, type CompileOptions, type CompileResult, type CompiledDefine, type ComponentSpec, type DataRead, type Diagnostic, ELEMENT, type Edit, type EditFailure, type EditFailureReason, type Hoisted, type Jig, type JigsNode, type Library, type ProcedureUse, type Program, type ProgramOutput, type PropSpec, type RenderNode, SEARCH_MARKER, type Statement, applyEdits, columnAt, compileJigs, compileLibrary, editBreakage, hoistDeclarations, isEditReply, jigSignature, lineAt, nearest, parseEdits, parseJigs, rangeIn, spanIn };
package/dist/index.js CHANGED
@@ -4,6 +4,6 @@ import { ELEMENT } from "./check-code.js";
4
4
  import { parseJigs } from "./parse.js";
5
5
  import { hoistDeclarations } from "./hoist.js";
6
6
  import { compileJigs, compileLibrary } from "./compile.js";
7
- import { recipeSignature } from "./signature.js";
7
+ import { jigSignature } from "./signature.js";
8
8
  import { SEARCH_MARKER, applyEdits, editBreakage, isEditReply, parseEdits } from "./patch.js";
9
- export { ELEMENT, SEARCH_MARKER, applyEdits, columnAt, compileJigs, compileLibrary, editBreakage, hoistDeclarations, isEditReply, lineAt, nearest, parseEdits, parseJigs, rangeIn, recipeSignature, spanIn };
9
+ export { ELEMENT, SEARCH_MARKER, applyEdits, columnAt, compileJigs, compileLibrary, editBreakage, hoistDeclarations, isEditReply, jigSignature, lineAt, nearest, parseEdits, parseJigs, rangeIn, spanIn };
package/dist/patch.d.ts CHANGED
@@ -13,11 +13,13 @@ export declare function isEditReply(text: string): boolean | null;
13
13
  export declare function parseEdits(text: string): Array<Edit>;
14
14
  /**
15
15
  * Why an edit was rejected. `missing`: its SEARCH is not in the document.
16
- * `ambiguous`: its SEARCH is there more than once. `malformed`: the block
17
- * itself is broken. `broken`: it applied, but the result needs parser repairs
18
- * the document did not (see `editBreakage`); the server reports this one.
16
+ * `ambiguous`: its SEARCH is there more than once. `overlapping`: its SEARCH
17
+ * spans lines an earlier edit of the same reply also changes. `malformed`:
18
+ * the block itself is broken. `broken`: it applied, but the result needs
19
+ * parser repairs the document did not (see `editBreakage`); the server
20
+ * reports this one.
19
21
  */
20
- export type EditFailureReason = "ambiguous" | "broken" | "malformed" | "missing";
22
+ export type EditFailureReason = "ambiguous" | "broken" | "malformed" | "missing" | "overlapping";
21
23
  export interface EditFailure {
22
24
  /** For `broken`: the repairs the edited document needs and the base did not. */
23
25
  breakage?: ReadonlyArray<{
@@ -25,8 +27,13 @@ export interface EditFailure {
25
27
  message: string;
26
28
  }>;
27
29
  failed: Edit;
28
- /** For `ambiguous`: the line each match starts on. */
30
+ /**
31
+ * For `ambiguous`: the line each match starts on. For `overlapping`: the
32
+ * line the earlier edit's SEARCH starts on, then this one's.
33
+ */
29
34
  lines?: ReadonlyArray<number>;
35
+ /** For `overlapping`: the earlier edit whose lines this one also changes. */
36
+ overlaps?: Edit;
30
37
  reason: EditFailureReason;
31
38
  }
32
39
  export type ApplyResult = (EditFailure & {
@@ -36,10 +43,15 @@ export type ApplyResult = (EditFailure & {
36
43
  text: string;
37
44
  };
38
45
  /**
39
- * Applies edits in order. Each SEARCH must appear in the document exactly
40
- * once, exactly or ignoring indentation; an empty SEARCH appends. Stops at
41
- * the first edit that doesn't match, matches more than once, or whose
42
- * REPLACE still contains edit markers.
46
+ * Applies a reply's edits to the document it was written against. Every
47
+ * SEARCH is located in that document first, exactly or ignoring
48
+ * indentation, and must be there once; the replacements are then made from
49
+ * the end, so one edit's REPLACE never moves or breaks another's anchor. An
50
+ * empty SEARCH appends. A SEARCH that is not in the document, or that spans
51
+ * lines an earlier edit's SEARCH spans, applies to the text as the edits
52
+ * before it leave it when it is there once, as edits written one after
53
+ * another; the edits after it anchor to that text. Otherwise it fails as
54
+ * `missing` or `overlapping`. Stops at the first edit that fails.
43
55
  */
44
56
  export declare function applyEdits(base: string, edits: ReadonlyArray<Edit>): ApplyResult;
45
57
  /**
package/dist/patch.js CHANGED
@@ -40,18 +40,39 @@ function parseEdits(text) {
40
40
  }
41
41
  return edits;
42
42
  }
43
- /** Starts of every line range in `lines` matching `search` when leading and trailing whitespace is ignored. */
44
- function findLoose(lines, search) {
45
- const target = search.map((line) => line.trim());
46
- const starts = [];
47
- for (let start = 0; start + target.length <= lines.length; start++) if (target.every((line, offset) => lines[start + offset]?.trim() === line)) starts.push(start);
48
- return starts;
43
+ /** Every line range of `text` matching `search` when leading and trailing whitespace is ignored. */
44
+ function findLoose(text, search) {
45
+ const lines = text.split("\n");
46
+ const target = search.split("\n").map((line) => line.trim());
47
+ const offsets = [];
48
+ let offset = 0;
49
+ for (const line of lines) {
50
+ offsets.push(offset);
51
+ offset += line.length + 1;
52
+ }
53
+ const ranges = [];
54
+ for (let start = 0; start + target.length <= lines.length; start++) {
55
+ const last = start + target.length - 1;
56
+ if (target.every((line, index) => lines[start + index]?.trim() === line)) ranges.push({
57
+ end: (offsets[last] ?? 0) + (lines[last]?.length ?? 0),
58
+ start: offsets[start] ?? 0
59
+ });
60
+ }
61
+ return ranges;
49
62
  }
50
- /** Every index at which `search` occurs in `text`, without overlaps. */
63
+ /** Every range at which `search` occurs in `text`, without overlaps. */
51
64
  function findExact(text, search) {
52
- const indexes = [];
53
- for (let index = text.indexOf(search); index !== -1; index = text.indexOf(search, index + search.length)) indexes.push(index);
54
- return indexes;
65
+ const ranges = [];
66
+ for (let index = text.indexOf(search); index !== -1; index = text.indexOf(search, index + search.length)) ranges.push({
67
+ end: index + search.length,
68
+ start: index
69
+ });
70
+ return ranges;
71
+ }
72
+ /** Where `search` is in `text`: exactly if it is there, else ignoring indentation. */
73
+ function locate(text, search) {
74
+ const exact = findExact(text, search);
75
+ return exact.length > 0 ? exact : findLoose(text, search);
55
76
  }
56
77
  const lineAt = (text, index) => text.slice(0, index).split("\n").length;
57
78
  const MARKERS = /* @__PURE__ */ new Set([
@@ -61,13 +82,31 @@ const MARKERS = /* @__PURE__ */ new Set([
61
82
  ]);
62
83
  const hasMarker = (text) => text.split("\n").some((line) => MARKERS.has(line.trim()));
63
84
  /**
64
- * Applies edits in order. Each SEARCH must appear in the document exactly
65
- * once, exactly or ignoring indentation; an empty SEARCH appends. Stops at
66
- * the first edit that doesn't match, matches more than once, or whose
67
- * REPLACE still contains edit markers.
85
+ * `text` with the anchored replacements made from the end, so none moves
86
+ * another's range, then the appends in order.
87
+ */
88
+ function applyAnchored(text, anchored, appended) {
89
+ let result = text;
90
+ const fromEnd = anchored.toSorted((a, b) => b.range.start - a.range.start);
91
+ for (const place of fromEnd) result = result.slice(0, place.range.start) + place.edit.replace + result.slice(place.range.end);
92
+ for (const replace of appended) result = `${result.trimEnd()}\n${replace}`;
93
+ return result;
94
+ }
95
+ /**
96
+ * Applies a reply's edits to the document it was written against. Every
97
+ * SEARCH is located in that document first, exactly or ignoring
98
+ * indentation, and must be there once; the replacements are then made from
99
+ * the end, so one edit's REPLACE never moves or breaks another's anchor. An
100
+ * empty SEARCH appends. A SEARCH that is not in the document, or that spans
101
+ * lines an earlier edit's SEARCH spans, applies to the text as the edits
102
+ * before it leave it when it is there once, as edits written one after
103
+ * another; the edits after it anchor to that text. Otherwise it fails as
104
+ * `missing` or `overlapping`. Stops at the first edit that fails.
68
105
  */
69
106
  function applyEdits(base, edits) {
70
107
  let text = base;
108
+ let anchored = [];
109
+ let appended = [];
71
110
  for (const edit of edits) {
72
111
  if (hasMarker(edit.replace)) return {
73
112
  failed: edit,
@@ -75,42 +114,49 @@ function applyEdits(base, edits) {
75
114
  reason: "malformed"
76
115
  };
77
116
  if (edit.search.trim() === "") {
78
- text = `${text.trimEnd()}\n${edit.replace}`;
117
+ appended.push(edit.replace);
79
118
  continue;
80
119
  }
81
- const exact = findExact(text, edit.search);
82
- if (exact.length > 1) return {
120
+ const ranges = locate(text, edit.search);
121
+ if (ranges.length > 1) return {
83
122
  failed: edit,
84
- lines: exact.map((index) => lineAt(text, index)),
123
+ lines: ranges.map((range) => lineAt(text, range.start)),
85
124
  ok: false,
86
125
  reason: "ambiguous"
87
126
  };
88
- const [index] = exact;
89
- if (index !== void 0) {
90
- text = text.slice(0, index) + edit.replace + text.slice(index + edit.search.length);
127
+ const [range] = ranges;
128
+ const overlap = range === void 0 ? void 0 : anchored.find((other) => range.start < other.range.end && other.range.start < range.end);
129
+ if (range !== void 0 && overlap === void 0) {
130
+ anchored.push({
131
+ edit,
132
+ range
133
+ });
91
134
  continue;
92
135
  }
93
- const lines = text.split("\n");
94
- const searchLines = edit.search.split("\n");
95
- const starts = findLoose(lines, searchLines);
96
- if (starts.length > 1) return {
136
+ const edited = applyAnchored(text, anchored, appended);
137
+ const later = locate(edited, edit.search);
138
+ const [found] = later;
139
+ if (found === void 0 || later.length > 1) return range === void 0 || overlap === void 0 ? {
97
140
  failed: edit,
98
- lines: starts.map((start) => start + 1),
99
141
  ok: false,
100
- reason: "ambiguous"
101
- };
102
- const [start] = starts;
103
- if (start === void 0) return {
142
+ reason: "missing"
143
+ } : {
104
144
  failed: edit,
145
+ lines: [lineAt(text, overlap.range.start), lineAt(text, range.start)],
105
146
  ok: false,
106
- reason: "missing"
147
+ overlaps: overlap.edit,
148
+ reason: "overlapping"
107
149
  };
108
- lines.splice(start, searchLines.length, ...edit.replace.split("\n"));
109
- text = lines.join("\n");
150
+ text = edited;
151
+ anchored = [{
152
+ edit,
153
+ range: found
154
+ }];
155
+ appended = [];
110
156
  }
111
157
  return {
112
158
  ok: true,
113
- text
159
+ text: applyAnchored(text, anchored, appended)
114
160
  };
115
161
  }
116
162
  /** Diagnostic codes the parser reports when it changed the source to make it parse. */
@@ -1,5 +1,5 @@
1
- import { Recipe } from "./compile.js";
1
+ import { Jig } from "./compile.js";
2
2
  //#region src/signature.d.ts
3
3
  /** `<statCard label value delta={0} note="">…</statCard>` when the define has a slot. */
4
- export declare function recipeSignature(recipe: Recipe): string;
4
+ export declare function jigSignature(jig: Jig): string;
5
5
  //#endregion
package/dist/signature.js CHANGED
@@ -14,12 +14,12 @@ function hasSlot(nodes) {
14
14
  return false;
15
15
  }
16
16
  /** `<statCard label value delta={0} note="">…</statCard>` when the define has a slot. */
17
- function recipeSignature(recipe) {
18
- const define = parseJigs(recipe.source).children.find((node) => node.type === "element" && node.name === "define");
19
- if (define === void 0) return `<${recipe.name}>`;
17
+ function jigSignature(jig) {
18
+ const define = parseJigs(jig.source).children.find((node) => node.type === "element" && node.name === "define");
19
+ if (define === void 0) return `<${jig.name}>`;
20
20
  const attrs = define.props.filter((prop) => prop.name !== "name").map((prop) => formatAttr(prop));
21
- const open = attrs.length === 0 ? `<${recipe.name}>` : `<${recipe.name} ${attrs.join(" ")}>`;
22
- return hasSlot(define.children) ? `${open}…</${recipe.name}>` : open;
21
+ const open = attrs.length === 0 ? `<${jig.name}>` : `<${jig.name} ${attrs.join(" ")}>`;
22
+ return hasSlot(define.children) ? `${open}…</${jig.name}>` : open;
23
23
  }
24
24
  //#endregion
25
- export { recipeSignature };
25
+ export { jigSignature };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jigs.design/compiler",
3
- "version": "0.2.0",
4
- "description": "Today's Jigs compiler: parser, checker against a catalog, code generator, recipes, and the edit helpers. The v2 rewrite replaces it.",
3
+ "version": "0.3.1",
4
+ "description": "Today's Jigs compiler: parser, checker against a catalog, code generator, jig libraries, and the edit helpers. The v2 rewrite replaces it.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -26,6 +26,6 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "acorn": "8.19.0",
29
- "@jigs.design/protocol": "0.2.0"
29
+ "@jigs.design/protocol": "0.3.1"
30
30
  }
31
31
  }