@motionscript/code 0.1.0-alpha.0 → 0.1.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/NOTICE +49 -0
  3. package/README.md +148 -50
  4. package/dist/browser/THIRD_PARTY_LICENSES.txt +431 -0
  5. package/dist/browser/index.js +10 -7
  6. package/dist/browser/index.js.map +3 -3
  7. package/dist/browser/manifest.json +85 -3
  8. package/dist/code-range.d.ts +7 -1
  9. package/dist/code-range.d.ts.map +1 -1
  10. package/dist/code-range.js +9 -1
  11. package/dist/code-range.js.map +1 -1
  12. package/dist/diff.d.ts +14 -0
  13. package/dist/diff.d.ts.map +1 -1
  14. package/dist/diff.js +134 -2
  15. package/dist/diff.js.map +1 -1
  16. package/dist/engine.d.ts +2 -2
  17. package/dist/engine.d.ts.map +1 -1
  18. package/dist/engine.js +4 -4
  19. package/dist/engine.js.map +1 -1
  20. package/dist/highlight.d.ts +10 -2
  21. package/dist/highlight.d.ts.map +1 -1
  22. package/dist/highlight.js +40 -6
  23. package/dist/highlight.js.map +1 -1
  24. package/dist/layout.d.ts +1 -1
  25. package/dist/layout.d.ts.map +1 -1
  26. package/dist/layout.js.map +1 -1
  27. package/dist/measure-cache.d.ts +2 -2
  28. package/dist/measure-cache.d.ts.map +1 -1
  29. package/dist/measure-cache.js +0 -0
  30. package/dist/measure-cache.js.map +1 -1
  31. package/dist/node.d.ts +275 -281
  32. package/dist/node.d.ts.map +1 -1
  33. package/dist/node.js +634 -700
  34. package/dist/node.js.map +1 -1
  35. package/dist/nodes.d.ts +6 -9
  36. package/dist/nodes.d.ts.map +1 -1
  37. package/dist/nodes.js +7 -9
  38. package/dist/nodes.js.map +1 -1
  39. package/dist/render.d.ts +10 -3
  40. package/dist/render.d.ts.map +1 -1
  41. package/dist/render.js +60 -1
  42. package/dist/render.js.map +1 -1
  43. package/dist/style.d.ts +3 -3
  44. package/dist/style.d.ts.map +1 -1
  45. package/dist/style.js +10 -6
  46. package/dist/style.js.map +1 -1
  47. package/dist/tokens.d.ts.map +1 -1
  48. package/dist/tokens.js +5 -1
  49. package/dist/tokens.js.map +1 -1
  50. package/dist/transitions.d.ts +19 -1
  51. package/dist/transitions.d.ts.map +1 -1
  52. package/dist/transitions.js.map +1 -1
  53. package/package.json +7 -4
  54. package/src/code-range.ts +10 -1
  55. package/src/diff.ts +137 -2
  56. package/src/engine.ts +5 -5
  57. package/src/highlight.ts +54 -5
  58. package/src/layout.ts +1 -1
  59. package/src/measure-cache.ts +0 -0
  60. package/src/node.ts +767 -747
  61. package/src/nodes.ts +8 -10
  62. package/src/render.ts +71 -3
  63. package/src/style.ts +11 -7
  64. package/src/tokens.ts +5 -1
  65. package/src/transitions.ts +21 -1
package/dist/style.d.ts CHANGED
@@ -20,7 +20,7 @@ export interface CodeStyleRule {
20
20
  * `@lezer/highlight`'s {@link tagHighlighter} resolves precedence.
21
21
  */
22
22
  export interface CodeHighlightStyle {
23
- /** Stable name, used as the highlighter cache key. */
23
+ /** Stable name, used to register the style and to refer to it from a `theme` prop. */
24
24
  name: string;
25
25
  /** Color applied to text with no matching tag. */
26
26
  defaultColor: string;
@@ -81,8 +81,8 @@ export type CodeThemeName = keyof typeof BUILTIN_THEMES;
81
81
  export type CodeTheme = CodeThemeName | (string & {}) | CodeHighlightStyle;
82
82
  /**
83
83
  * Compile a {@link CodeHighlightStyle} into a `@lezer/highlight` {@link Highlighter}
84
- * whose "class" output is the literal color string for each tag. Cached by style
85
- * name so repeated lookups (every tokenize) don't rebuild the matcher.
84
+ * whose "class" output is the literal color string for each tag. Cached per style
85
+ * object so repeated lookups (every tokenize) don't rebuild the matcher.
86
86
  */
87
87
  export declare function compileStyle(style: CodeHighlightStyle): Highlighter;
88
88
  //# sourceMappingURL=style.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,GAAG,EAA6B,MAAM,kBAAkB,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IAC/B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAwCnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,kBAiB7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAkB9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,kBAgC7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAgC9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;CAQmB,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,cAAc,CAAC;AAExD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,kBAAkB,CAAC;AAM3E;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,WAAW,CAQnE"}
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,GAAG,EAA6B,MAAM,kBAAkB,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IAC/B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,kBAwCnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,kBAiB7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAkB9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,kBAgC7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAgC9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;CAQmB,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,cAAc,CAAC;AAExD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,kBAAkB,CAAC;AAU3E;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,WAAW,CAQnE"}
package/dist/style.js CHANGED
@@ -184,20 +184,24 @@ export const BUILTIN_THEMES = {
184
184
  "vscode-dark": VscodeDarkStyle,
185
185
  "vscode-light": VscodeLightStyle,
186
186
  };
187
- // Cache one compiled Highlighter per style name. Compiling builds a tag-rule
187
+ // Cache one compiled Highlighter per style *object*. Compiling builds a tag-rule
188
188
  // matcher; the parsed result is pure data so it's safe to share across Code nodes.
189
- const compiledByName = new Map();
189
+ // Keyed by the object rather than its `name`: two styles may share a name (an
190
+ // inline theme, or one re-registered under the same name with new colours), and
191
+ // the second must not colour with the first one's rules. A WeakMap, so a style
192
+ // nothing refers to any more takes its matcher with it.
193
+ const compiledByStyle = new WeakMap();
190
194
  /**
191
195
  * Compile a {@link CodeHighlightStyle} into a `@lezer/highlight` {@link Highlighter}
192
- * whose "class" output is the literal color string for each tag. Cached by style
193
- * name so repeated lookups (every tokenize) don't rebuild the matcher.
196
+ * whose "class" output is the literal color string for each tag. Cached per style
197
+ * object so repeated lookups (every tokenize) don't rebuild the matcher.
194
198
  */
195
199
  export function compileStyle(style) {
196
- const cached = compiledByName.get(style.name);
200
+ const cached = compiledByStyle.get(style);
197
201
  if (cached)
198
202
  return cached;
199
203
  const highlighter = tagHighlighter(style.rules.map(rule => ({ tag: rule.tag, class: rule.color })));
200
- compiledByName.set(style.name, highlighter);
204
+ compiledByStyle.set(style, highlighter);
201
205
  return highlighter;
202
206
  }
203
207
  //# sourceMappingURL=style.js.map
package/dist/style.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"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","sourcesContent":["import { Highlighter, Tag, tagHighlighter, tags as t } from \"@lezer/highlight\";\n\n/**\n * A single style rule: map one or more Lezer highlight {@link Tag}s to a color.\n * This mirrors a `@codemirror/language` HighlightStyle entry, but instead of\n * emitting CSS class names it carries the color directly — we render to a canvas,\n * not the DOM, so there is no stylesheet to resolve against.\n */\nexport interface CodeStyleRule {\n tag: Tag | readonly Tag[];\n color: string;\n}\n\n/**\n * A code theme: an ordered list of tag→color rules plus a fallback color for any\n * text the parser produces no highlight tag for (operators, punctuation, plain\n * identifiers in some grammars, etc.). Pass a custom one via the Code node's\n * `theme` prop to recolor highlighting without touching the highlighter wiring.\n *\n * @remarks\n * Later rules win when several match the same tag, matching how\n * `@lezer/highlight`'s {@link tagHighlighter} resolves precedence.\n */\nexport interface CodeHighlightStyle {\n /** Stable name, used as the highlighter cache key. */\n name: string;\n /** Color applied to text with no matching tag. */\n defaultColor: string;\n rules: CodeStyleRule[];\n}\n\n/**\n * Motion Canvas's default highlight palette (a Nord-derived theme), ported from\n * `@motion-canvas/2d`'s DefaultHighlightStyle so highlighting matches Motion\n * Canvas token-for-token. Colors and tag groupings are kept identical; only the\n * shape changes (color strings in place of CSS rules).\n */\nexport const DefaultHighlightStyle: CodeHighlightStyle = {\n name: \"motion-canvas-default\",\n defaultColor: \"#d8dee9\",\n rules: [\n { tag: t.keyword, color: \"#5e81ac\" },\n { tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName], color: \"#88c0d0\" },\n { tag: [t.variableName], color: \"#8fbcbb\" },\n { tag: [t.function(t.variableName)], color: \"#8fbcbb\" },\n { tag: [t.labelName], color: \"#81a1c1\" },\n { tag: [t.color, t.constant(t.name), t.standard(t.name)], color: \"#5e81ac\" },\n { tag: [t.definition(t.name), t.separator], color: \"#a3be8c\" },\n { tag: [t.brace], color: \"#8fbcbb\" },\n { tag: [t.annotation], color: \"#d30102\" },\n { tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: \"#b48ead\" },\n { tag: [t.typeName, t.className], color: \"#ECEFF4\" },\n { tag: [t.operator, t.operatorKeyword], color: \"#a3be8c\" },\n { tag: [t.tagName], color: \"#b48ead\" },\n { tag: [t.squareBracket], color: \"#ECEFF4\" },\n { tag: [t.angleBracket], color: \"#ECEFF4\" },\n { tag: [t.attributeName], color: \"#eceff4\" },\n { tag: [t.regexp], color: \"#5e81ac\" },\n { tag: [t.quote], color: \"#b48ead\" },\n { tag: [t.string], color: \"#a3be8c\" },\n { tag: t.link, color: \"#a3be8c\" },\n { tag: [t.url, t.escape, t.special(t.string)], color: \"#8fbcbb\" },\n { tag: [t.meta], color: \"#88c0d0\" },\n { tag: [t.monospace], color: \"#d8dee9\" },\n { tag: [t.comment], color: \"#4c566a\" },\n { tag: t.strong, color: \"#5e81ac\" },\n { tag: t.emphasis, color: \"#5e81ac\" },\n { tag: t.heading, color: \"#5e81ac\" },\n { tag: t.special(t.heading1), color: \"#5e81ac\" },\n { tag: t.heading1, color: \"#5e81ac\" },\n { tag: [t.heading2, t.heading3, t.heading4], color: \"#5e81ac\" },\n { tag: [t.heading5, t.heading6], color: \"#5e81ac\" },\n { tag: [t.atom, t.bool, t.special(t.variableName)], color: \"#d08770\" },\n { tag: [t.processingInstruction, t.inserted], color: \"#8fbcbb\" },\n { tag: [t.contentSeparator], color: \"#ebcb8b\" },\n { tag: t.invalid, color: \"#434c5e\" },\n ],\n};\n\n/**\n * GitHub Dark highlight palette, adapted from `@uiw/codemirror-theme-github`.\n * `defaultColor` is GitHub's editor foreground (`#c9d1d9`), used for any text the\n * parser tags don't cover. DOM-only style props (backgroundColor, textDecoration,\n * fontWeight, fontStyle) are dropped — we only color tokens on the canvas.\n */\nexport const GithubDarkStyle: CodeHighlightStyle = {\n name: \"github-dark\",\n defaultColor: \"#c9d1d9\",\n rules: [\n { tag: [t.standard(t.tagName), t.tagName], color: \"#7ee787\" },\n { tag: [t.comment, t.bracket], color: \"#8b949e\" },\n { tag: [t.className, t.propertyName], color: \"#d2a8ff\" },\n { tag: [t.variableName, t.attributeName, t.number, t.operator], color: \"#79c0ff\" },\n { tag: [t.keyword, t.typeName, t.typeOperator], color: \"#ff7b72\" },\n { tag: [t.string, t.meta, t.regexp], color: \"#a5d6ff\" },\n { tag: [t.name, t.quote], color: \"#7ee787\" },\n { tag: [t.heading, t.strong], color: \"#d2a8ff\" },\n { tag: [t.emphasis], color: \"#d2a8ff\" },\n { tag: [t.deleted], color: \"#ffdcd7\" },\n { tag: [t.atom, t.bool, t.special(t.variableName)], color: \"#ffab70\" },\n { tag: t.invalid, color: \"#f97583\" },\n ],\n};\n\n/**\n * GitHub Light highlight palette, adapted from `@uiw/codemirror-theme-github`.\n * `defaultColor` is GitHub's editor foreground (`#24292e`). See {@link GithubDarkStyle}\n * for the note on dropped DOM-only style props.\n */\nexport const GithubLightStyle: CodeHighlightStyle = {\n name: \"github-light\",\n defaultColor: \"#24292e\",\n rules: [\n { tag: [t.standard(t.tagName), t.tagName], color: \"#116329\" },\n { tag: [t.comment, t.bracket], color: \"#6a737d\" },\n { tag: [t.className, t.propertyName], color: \"#6f42c1\" },\n { tag: [t.variableName, t.attributeName, t.number, t.operator], color: \"#005cc5\" },\n { tag: [t.keyword, t.typeName, t.typeOperator], color: \"#d73a49\" },\n { tag: [t.string, t.meta, t.regexp], color: \"#032f62\" },\n { tag: [t.name, t.quote], color: \"#22863a\" },\n { tag: [t.heading, t.strong], color: \"#24292e\" },\n { tag: [t.emphasis], color: \"#24292e\" },\n { tag: [t.deleted], color: \"#b31d28\" },\n { tag: [t.atom, t.bool, t.special(t.variableName)], color: \"#e36209\" },\n { tag: [t.url, t.escape, t.regexp, t.link], color: \"#032f62\" },\n { tag: t.invalid, color: \"#cb2431\" },\n ],\n};\n\n/**\n * VS Code Dark+ highlight palette, adapted from the `@uiw/codemirror-theme-vscode`\n * snippet. `defaultColor` is VS Code's editor foreground (`#9cdcfe`). DOM-only\n * style props are dropped; later rules win, matching {@link tagHighlighter}.\n */\nexport const VscodeDarkStyle: CodeHighlightStyle = {\n name: \"vscode-dark\",\n defaultColor: \"#9cdcfe\",\n rules: [\n {\n tag: [\n t.keyword, t.operatorKeyword, t.modifier, t.color,\n t.constant(t.name), t.standard(t.name), t.standard(t.tagName),\n t.special(t.brace), t.atom, t.bool, t.special(t.variableName),\n ],\n color: \"#569cd6\",\n },\n { tag: [t.controlKeyword, t.moduleKeyword], color: \"#c586c0\" },\n {\n tag: [\n t.name, t.deleted, t.character, t.macroName, t.propertyName,\n t.variableName, t.labelName, t.definition(t.name),\n ],\n color: \"#9cdcfe\",\n },\n { tag: t.heading, color: \"#9cdcfe\" },\n { tag: [t.typeName, t.className, t.tagName, t.changed, t.annotation, t.self, t.namespace], color: \"#4ec9b0\" },\n { tag: [t.function(t.variableName), t.function(t.propertyName)], color: \"#dcdcaa\" },\n { tag: [t.number], color: \"#b5cea8\" },\n { tag: [t.operator, t.punctuation, t.separator, t.url, t.escape], color: \"#d4d4d4\" },\n { tag: [t.regexp], color: \"#d16969\" },\n { tag: [t.special(t.string), t.processingInstruction, t.string, t.inserted], color: \"#ce9178\" },\n { tag: [t.angleBracket], color: \"#808080\" },\n { tag: [t.meta, t.comment], color: \"#6a9955\" },\n { tag: t.link, color: \"#6a9955\" },\n { tag: t.invalid, color: \"#ff0000\" },\n ],\n};\n\n/**\n * VS Code Light+ highlight palette, adapted from the `@uiw/codemirror-theme-vscode`\n * snippet. `defaultColor` is VS Code's editor foreground (`#383a42`). See\n * {@link VscodeDarkStyle} for the note on dropped DOM-only style props.\n */\nexport const VscodeLightStyle: CodeHighlightStyle = {\n name: \"vscode-light\",\n defaultColor: \"#383a42\",\n rules: [\n {\n tag: [\n t.keyword, t.operatorKeyword, t.modifier, t.color,\n t.constant(t.name), t.standard(t.name), t.standard(t.tagName),\n t.special(t.brace), t.atom, t.bool, t.special(t.variableName),\n ],\n color: \"#0000ff\",\n },\n { tag: [t.moduleKeyword, t.controlKeyword], color: \"#af00db\" },\n {\n tag: [\n t.name, t.deleted, t.character, t.macroName, t.propertyName,\n t.variableName, t.labelName, t.definition(t.name),\n ],\n color: \"#0070c1\",\n },\n { tag: t.heading, color: \"#0070c1\" },\n { tag: [t.typeName, t.className, t.tagName, t.changed, t.annotation, t.self, t.namespace], color: \"#267f99\" },\n { tag: [t.function(t.variableName), t.function(t.propertyName)], color: \"#795e26\" },\n { tag: [t.number], color: \"#098658\" },\n { tag: [t.operator, t.punctuation, t.separator, t.url, t.escape], color: \"#383a42\" },\n { tag: [t.regexp], color: \"#af00db\" },\n { tag: [t.special(t.string), t.processingInstruction, t.string, t.inserted], color: \"#a31515\" },\n { tag: [t.angleBracket], color: \"#383a42\" },\n { tag: [t.meta, t.comment], color: \"#008000\" },\n { tag: t.link, color: \"#4078f2\" },\n { tag: t.invalid, color: \"#e45649\" },\n ],\n};\n\n/**\n * The built-in themes, keyed by their string name. {@link CodeThemeName} is the\n * union of these keys — pass one of those strings (or any {@link CodeHighlightStyle}\n * object) to a Code node's `theme` prop.\n */\nexport const BUILTIN_THEMES = {\n // Literal keys (not computed from `.name`) so `keyof` yields a string-literal\n // union for CodeThemeName; these must stay in sync with each style's `name`.\n \"motion-canvas-default\": DefaultHighlightStyle,\n \"github-dark\": GithubDarkStyle,\n \"github-light\": GithubLightStyle,\n \"vscode-dark\": VscodeDarkStyle,\n \"vscode-light\": VscodeLightStyle,\n} satisfies Record<string, CodeHighlightStyle>;\n\n/** Names of the built-in themes, e.g. `'github-dark' | 'github-light'`. */\nexport type CodeThemeName = keyof typeof BUILTIN_THEMES;\n\n/**\n * What a Code node's `theme` prop accepts: a built-in theme name (with\n * autocomplete), any other registered theme name, or a {@link CodeHighlightStyle}\n * object passed inline. The `string & {}` keeps the literal-name suggestions while\n * still allowing arbitrary registered names.\n */\nexport type CodeTheme = CodeThemeName | (string & {}) | CodeHighlightStyle;\n\n// Cache one compiled Highlighter per style name. Compiling builds a tag-rule\n// matcher; the parsed result is pure data so it's safe to share across Code nodes.\nconst compiledByName = new Map<string, Highlighter>();\n\n/**\n * Compile a {@link CodeHighlightStyle} into a `@lezer/highlight` {@link Highlighter}\n * whose \"class\" output is the literal color string for each tag. Cached by style\n * name so repeated lookups (every tokenize) don't rebuild the matcher.\n */\nexport function compileStyle(style: CodeHighlightStyle): Highlighter {\n const cached = compiledByName.get(style.name);\n if (cached) return cached;\n const highlighter = tagHighlighter(\n style.rules.map(rule => ({ tag: rule.tag, class: rule.color })),\n );\n compiledByName.set(style.name, highlighter);\n return highlighter;\n}\n"]}
1
+ {"version":3,"file":"style.js","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"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","sourcesContent":["import { Highlighter, Tag, tagHighlighter, tags as t } from \"@lezer/highlight\";\n\n/**\n * A single style rule: map one or more Lezer highlight {@link Tag}s to a color.\n * This mirrors a `@codemirror/language` HighlightStyle entry, but instead of\n * emitting CSS class names it carries the color directly — we render to a canvas,\n * not the DOM, so there is no stylesheet to resolve against.\n */\nexport interface CodeStyleRule {\n tag: Tag | readonly Tag[];\n color: string;\n}\n\n/**\n * A code theme: an ordered list of tag→color rules plus a fallback color for any\n * text the parser produces no highlight tag for (operators, punctuation, plain\n * identifiers in some grammars, etc.). Pass a custom one via the Code node's\n * `theme` prop to recolor highlighting without touching the highlighter wiring.\n *\n * @remarks\n * Later rules win when several match the same tag, matching how\n * `@lezer/highlight`'s {@link tagHighlighter} resolves precedence.\n */\nexport interface CodeHighlightStyle {\n /** Stable name, used to register the style and to refer to it from a `theme` prop. */\n name: string;\n /** Color applied to text with no matching tag. */\n defaultColor: string;\n rules: CodeStyleRule[];\n}\n\n/**\n * Motion Canvas's default highlight palette (a Nord-derived theme), ported from\n * `@motion-canvas/2d`'s DefaultHighlightStyle so highlighting matches Motion\n * Canvas token-for-token. Colors and tag groupings are kept identical; only the\n * shape changes (color strings in place of CSS rules).\n */\nexport const DefaultHighlightStyle: CodeHighlightStyle = {\n name: \"motion-canvas-default\",\n defaultColor: \"#d8dee9\",\n rules: [\n { tag: t.keyword, color: \"#5e81ac\" },\n { tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName], color: \"#88c0d0\" },\n { tag: [t.variableName], color: \"#8fbcbb\" },\n { tag: [t.function(t.variableName)], color: \"#8fbcbb\" },\n { tag: [t.labelName], color: \"#81a1c1\" },\n { tag: [t.color, t.constant(t.name), t.standard(t.name)], color: \"#5e81ac\" },\n { tag: [t.definition(t.name), t.separator], color: \"#a3be8c\" },\n { tag: [t.brace], color: \"#8fbcbb\" },\n { tag: [t.annotation], color: \"#d30102\" },\n { tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: \"#b48ead\" },\n { tag: [t.typeName, t.className], color: \"#ECEFF4\" },\n { tag: [t.operator, t.operatorKeyword], color: \"#a3be8c\" },\n { tag: [t.tagName], color: \"#b48ead\" },\n { tag: [t.squareBracket], color: \"#ECEFF4\" },\n { tag: [t.angleBracket], color: \"#ECEFF4\" },\n { tag: [t.attributeName], color: \"#eceff4\" },\n { tag: [t.regexp], color: \"#5e81ac\" },\n { tag: [t.quote], color: \"#b48ead\" },\n { tag: [t.string], color: \"#a3be8c\" },\n { tag: t.link, color: \"#a3be8c\" },\n { tag: [t.url, t.escape, t.special(t.string)], color: \"#8fbcbb\" },\n { tag: [t.meta], color: \"#88c0d0\" },\n { tag: [t.monospace], color: \"#d8dee9\" },\n { tag: [t.comment], color: \"#4c566a\" },\n { tag: t.strong, color: \"#5e81ac\" },\n { tag: t.emphasis, color: \"#5e81ac\" },\n { tag: t.heading, color: \"#5e81ac\" },\n { tag: t.special(t.heading1), color: \"#5e81ac\" },\n { tag: t.heading1, color: \"#5e81ac\" },\n { tag: [t.heading2, t.heading3, t.heading4], color: \"#5e81ac\" },\n { tag: [t.heading5, t.heading6], color: \"#5e81ac\" },\n { tag: [t.atom, t.bool, t.special(t.variableName)], color: \"#d08770\" },\n { tag: [t.processingInstruction, t.inserted], color: \"#8fbcbb\" },\n { tag: [t.contentSeparator], color: \"#ebcb8b\" },\n { tag: t.invalid, color: \"#434c5e\" },\n ],\n};\n\n/**\n * GitHub Dark highlight palette, adapted from `@uiw/codemirror-theme-github`.\n * `defaultColor` is GitHub's editor foreground (`#c9d1d9`), used for any text the\n * parser tags don't cover. DOM-only style props (backgroundColor, textDecoration,\n * fontWeight, fontStyle) are dropped — we only color tokens on the canvas.\n */\nexport const GithubDarkStyle: CodeHighlightStyle = {\n name: \"github-dark\",\n defaultColor: \"#c9d1d9\",\n rules: [\n { tag: [t.standard(t.tagName), t.tagName], color: \"#7ee787\" },\n { tag: [t.comment, t.bracket], color: \"#8b949e\" },\n { tag: [t.className, t.propertyName], color: \"#d2a8ff\" },\n { tag: [t.variableName, t.attributeName, t.number, t.operator], color: \"#79c0ff\" },\n { tag: [t.keyword, t.typeName, t.typeOperator], color: \"#ff7b72\" },\n { tag: [t.string, t.meta, t.regexp], color: \"#a5d6ff\" },\n { tag: [t.name, t.quote], color: \"#7ee787\" },\n { tag: [t.heading, t.strong], color: \"#d2a8ff\" },\n { tag: [t.emphasis], color: \"#d2a8ff\" },\n { tag: [t.deleted], color: \"#ffdcd7\" },\n { tag: [t.atom, t.bool, t.special(t.variableName)], color: \"#ffab70\" },\n { tag: t.invalid, color: \"#f97583\" },\n ],\n};\n\n/**\n * GitHub Light highlight palette, adapted from `@uiw/codemirror-theme-github`.\n * `defaultColor` is GitHub's editor foreground (`#24292e`). See {@link GithubDarkStyle}\n * for the note on dropped DOM-only style props.\n */\nexport const GithubLightStyle: CodeHighlightStyle = {\n name: \"github-light\",\n defaultColor: \"#24292e\",\n rules: [\n { tag: [t.standard(t.tagName), t.tagName], color: \"#116329\" },\n { tag: [t.comment, t.bracket], color: \"#6a737d\" },\n { tag: [t.className, t.propertyName], color: \"#6f42c1\" },\n { tag: [t.variableName, t.attributeName, t.number, t.operator], color: \"#005cc5\" },\n { tag: [t.keyword, t.typeName, t.typeOperator], color: \"#d73a49\" },\n { tag: [t.string, t.meta, t.regexp], color: \"#032f62\" },\n { tag: [t.name, t.quote], color: \"#22863a\" },\n { tag: [t.heading, t.strong], color: \"#24292e\" },\n { tag: [t.emphasis], color: \"#24292e\" },\n { tag: [t.deleted], color: \"#b31d28\" },\n { tag: [t.atom, t.bool, t.special(t.variableName)], color: \"#e36209\" },\n { tag: [t.url, t.escape, t.regexp, t.link], color: \"#032f62\" },\n { tag: t.invalid, color: \"#cb2431\" },\n ],\n};\n\n/**\n * VS Code Dark+ highlight palette, adapted from the `@uiw/codemirror-theme-vscode`\n * snippet. `defaultColor` is VS Code's editor foreground (`#9cdcfe`). DOM-only\n * style props are dropped; later rules win, matching {@link tagHighlighter}.\n */\nexport const VscodeDarkStyle: CodeHighlightStyle = {\n name: \"vscode-dark\",\n defaultColor: \"#9cdcfe\",\n rules: [\n {\n tag: [\n t.keyword, t.operatorKeyword, t.modifier, t.color,\n t.constant(t.name), t.standard(t.name), t.standard(t.tagName),\n t.special(t.brace), t.atom, t.bool, t.special(t.variableName),\n ],\n color: \"#569cd6\",\n },\n { tag: [t.controlKeyword, t.moduleKeyword], color: \"#c586c0\" },\n {\n tag: [\n t.name, t.deleted, t.character, t.macroName, t.propertyName,\n t.variableName, t.labelName, t.definition(t.name),\n ],\n color: \"#9cdcfe\",\n },\n { tag: t.heading, color: \"#9cdcfe\" },\n { tag: [t.typeName, t.className, t.tagName, t.changed, t.annotation, t.self, t.namespace], color: \"#4ec9b0\" },\n { tag: [t.function(t.variableName), t.function(t.propertyName)], color: \"#dcdcaa\" },\n { tag: [t.number], color: \"#b5cea8\" },\n { tag: [t.operator, t.punctuation, t.separator, t.url, t.escape], color: \"#d4d4d4\" },\n { tag: [t.regexp], color: \"#d16969\" },\n { tag: [t.special(t.string), t.processingInstruction, t.string, t.inserted], color: \"#ce9178\" },\n { tag: [t.angleBracket], color: \"#808080\" },\n { tag: [t.meta, t.comment], color: \"#6a9955\" },\n { tag: t.link, color: \"#6a9955\" },\n { tag: t.invalid, color: \"#ff0000\" },\n ],\n};\n\n/**\n * VS Code Light+ highlight palette, adapted from the `@uiw/codemirror-theme-vscode`\n * snippet. `defaultColor` is VS Code's editor foreground (`#383a42`). See\n * {@link VscodeDarkStyle} for the note on dropped DOM-only style props.\n */\nexport const VscodeLightStyle: CodeHighlightStyle = {\n name: \"vscode-light\",\n defaultColor: \"#383a42\",\n rules: [\n {\n tag: [\n t.keyword, t.operatorKeyword, t.modifier, t.color,\n t.constant(t.name), t.standard(t.name), t.standard(t.tagName),\n t.special(t.brace), t.atom, t.bool, t.special(t.variableName),\n ],\n color: \"#0000ff\",\n },\n { tag: [t.moduleKeyword, t.controlKeyword], color: \"#af00db\" },\n {\n tag: [\n t.name, t.deleted, t.character, t.macroName, t.propertyName,\n t.variableName, t.labelName, t.definition(t.name),\n ],\n color: \"#0070c1\",\n },\n { tag: t.heading, color: \"#0070c1\" },\n { tag: [t.typeName, t.className, t.tagName, t.changed, t.annotation, t.self, t.namespace], color: \"#267f99\" },\n { tag: [t.function(t.variableName), t.function(t.propertyName)], color: \"#795e26\" },\n { tag: [t.number], color: \"#098658\" },\n { tag: [t.operator, t.punctuation, t.separator, t.url, t.escape], color: \"#383a42\" },\n { tag: [t.regexp], color: \"#af00db\" },\n { tag: [t.special(t.string), t.processingInstruction, t.string, t.inserted], color: \"#a31515\" },\n { tag: [t.angleBracket], color: \"#383a42\" },\n { tag: [t.meta, t.comment], color: \"#008000\" },\n { tag: t.link, color: \"#4078f2\" },\n { tag: t.invalid, color: \"#e45649\" },\n ],\n};\n\n/**\n * The built-in themes, keyed by their string name. {@link CodeThemeName} is the\n * union of these keys — pass one of those strings (or any {@link CodeHighlightStyle}\n * object) to a Code node's `theme` prop.\n */\nexport const BUILTIN_THEMES = {\n // Literal keys (not computed from `.name`) so `keyof` yields a string-literal\n // union for CodeThemeName; these must stay in sync with each style's `name`.\n \"motion-canvas-default\": DefaultHighlightStyle,\n \"github-dark\": GithubDarkStyle,\n \"github-light\": GithubLightStyle,\n \"vscode-dark\": VscodeDarkStyle,\n \"vscode-light\": VscodeLightStyle,\n} satisfies Record<string, CodeHighlightStyle>;\n\n/** Names of the built-in themes, e.g. `'github-dark' | 'github-light'`. */\nexport type CodeThemeName = keyof typeof BUILTIN_THEMES;\n\n/**\n * What a Code node's `theme` prop accepts: a built-in theme name (with\n * autocomplete), any other registered theme name, or a {@link CodeHighlightStyle}\n * object passed inline. The `string & {}` keeps the literal-name suggestions while\n * still allowing arbitrary registered names.\n */\nexport type CodeTheme = CodeThemeName | (string & {}) | CodeHighlightStyle;\n\n// Cache one compiled Highlighter per style *object*. Compiling builds a tag-rule\n// matcher; the parsed result is pure data so it's safe to share across Code nodes.\n// Keyed by the object rather than its `name`: two styles may share a name (an\n// inline theme, or one re-registered under the same name with new colours), and\n// the second must not colour with the first one's rules. A WeakMap, so a style\n// nothing refers to any more takes its matcher with it.\nconst compiledByStyle = new WeakMap<CodeHighlightStyle, Highlighter>();\n\n/**\n * Compile a {@link CodeHighlightStyle} into a `@lezer/highlight` {@link Highlighter}\n * whose \"class\" output is the literal color string for each tag. Cached per style\n * object so repeated lookups (every tokenize) don't rebuild the matcher.\n */\nexport function compileStyle(style: CodeHighlightStyle): Highlighter {\n const cached = compiledByStyle.get(style);\n if (cached) return cached;\n const highlighter = tagHighlighter(\n style.rules.map(rule => ({ tag: rule.tag, class: rule.color })),\n );\n compiledByStyle.set(style, highlighter);\n return highlighter;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAMpC,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,WAAW,MAAM;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,EAAE,CAAC;CACrB;AAQD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAEpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAUhG;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CACzB,MAAM,EAAE,OAAO,EAAE,EACjB,GAAG,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,CAmBzC"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAMpC,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,WAAW,MAAM;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,EAAE,CAAC;CACrB;AAQD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAEpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAchG;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CACzB,MAAM,EAAE,OAAO,EAAE,EACjB,GAAG,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,CAmBzC"}
package/dist/tokens.js CHANGED
@@ -1,4 +1,4 @@
1
- import { canHighlight, highlightToTokens } from "./highlight.js";
1
+ import { canHighlight, highlightToTokens, normalizeSource, resolveTheme } from "./highlight.js";
2
2
  // Module-global, monotonic id counters shared across all Code nodes — ids only
3
3
  // need to be unique within a node, but a global counter is the simplest way to
4
4
  // guarantee that and never collides.
@@ -14,7 +14,11 @@ export function tokenizeCodeToIdLines(code, language, theme) {
14
14
  // Until the language parser has loaded (it streams in via the asset loader),
15
15
  // fall back to flat, uncolored lines instead of throwing on an unloaded
16
16
  // grammar. The node re-tokenizes once the load completes.
17
+ code = normalizeSource(code);
17
18
  if (!canHighlight(language, theme)) {
19
+ // Resolved for its warning: an unknown theme is reported whether or not
20
+ // the grammar has landed yet.
21
+ resolveTheme(theme);
18
22
  return code.split('\n').map(line => makeIdLine([makeIdToken(line, '#d1d5db')]));
19
23
  }
20
24
  return highlightToTokens(code, language, theme).map(line => makeIdLine(line.map(tok => makeIdToken(tok.content, tok.color))));
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAoB9D,+EAA+E;AAC/E,+EAA+E;AAC/E,qCAAqC;AACrC,IAAI,WAAW,GAAG,CAAC,CAAC;AACpB,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,KAAc;IACvD,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IACxC,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,QAAgB,EAAE,KAAgB;IAClF,6EAA6E;IAC7E,wEAAwE;IACxE,0DAA0D;IAC1D,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACvD,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CACnE,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CACzB,MAAiB,EACjB,GAAW;IAEX,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,CAAC;QACnB,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QACtC,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/D,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/D,CAAC;QACD,GAAG,GAAG,IAAI,CAAC;IACf,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import { canHighlight, highlightToTokens } from \"./highlight\";\nimport { CodeTheme } from \"./style\";\n\n// IdToken is our internal wrapper around a highlighter token that gives every\n// token a stable identity across line insertions/removals. All animation state\n// is keyed by `id`, so concurrent edits at different positions don't clobber\n// each other while one is mid-animation.\nexport interface IdToken {\n id: number;\n content: string;\n color?: string;\n}\n\n// IdLine wraps a row of tokens with its own stable id, so per-line animations\n// (heightScale during insert/remove) survive line insertions/removals.\nexport interface IdLine {\n id: number;\n tokens: IdToken[];\n}\n\n// Module-global, monotonic id counters shared across all Code nodes — ids only\n// need to be unique within a node, but a global counter is the simplest way to\n// guarantee that and never collides.\nlet nextTokenId = 1;\nlet nextLineId = 1;\n\nexport function makeIdToken(content: string, color?: string): IdToken {\n return { id: nextTokenId++, content, color };\n}\n\nexport function makeIdLine(tokens: IdToken[]): IdLine {\n return { id: nextLineId++, tokens };\n}\n\nexport function tokenizeCodeToIdLines(code: string, language: string, theme: CodeTheme): IdLine[] {\n // Until the language parser has loaded (it streams in via the asset loader),\n // fall back to flat, uncolored lines instead of throwing on an unloaded\n // grammar. The node re-tokenizes once the load completes.\n if (!canHighlight(language, theme)) {\n return code.split('\\n').map(line => makeIdLine([makeIdToken(line, '#d1d5db')]));\n }\n return highlightToTokens(code, language, theme).map(line =>\n makeIdLine(line.map(tok => makeIdToken(tok.content, tok.color))),\n );\n}\n\n/**\n * Split `tokens` at character offset `col` (relative to the joined content of\n * the tokens). If `col` falls inside a token, that token is split into two new\n * tokens with fresh ids (the original id is discarded — it didn't exist as a\n * single unit on either side of the cut).\n */\nexport function splitTokensAt(\n tokens: IdToken[],\n col: number,\n): { before: IdToken[]; after: IdToken[] } {\n const before: IdToken[] = [];\n const after: IdToken[] = [];\n let off = 0;\n for (const tok of tokens) {\n const tStart = off;\n const tEnd = off + tok.content.length;\n if (tEnd <= col) {\n before.push(tok);\n } else if (tStart >= col) {\n after.push(tok);\n } else {\n const cut = col - tStart;\n before.push(makeIdToken(tok.content.slice(0, cut), tok.color));\n after.push(makeIdToken(tok.content.slice(cut), tok.color));\n }\n off = tEnd;\n }\n return { before, after };\n}\n"]}
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoB7F,+EAA+E;AAC/E,+EAA+E;AAC/E,qCAAqC;AACrC,IAAI,WAAW,GAAG,CAAC,CAAC;AACpB,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,KAAc;IACvD,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IACxC,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,QAAgB,EAAE,KAAgB;IAClF,6EAA6E;IAC7E,wEAAwE;IACxE,0DAA0D;IAC1D,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;QACjC,wEAAwE;QACxE,8BAA8B;QAC9B,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACvD,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CACnE,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CACzB,MAAiB,EACjB,GAAW;IAEX,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,CAAC;QACnB,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QACtC,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/D,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/D,CAAC;QACD,GAAG,GAAG,IAAI,CAAC;IACf,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import { canHighlight, highlightToTokens, normalizeSource, resolveTheme } from \"./highlight\";\nimport { CodeTheme } from \"./style\";\n\n// IdToken is our internal wrapper around a highlighter token that gives every\n// token a stable identity across line insertions/removals. All animation state\n// is keyed by `id`, so concurrent edits at different positions don't clobber\n// each other while one is mid-animation.\nexport interface IdToken {\n id: number;\n content: string;\n color?: string;\n}\n\n// IdLine wraps a row of tokens with its own stable id, so per-line animations\n// (heightScale during insert/remove) survive line insertions/removals.\nexport interface IdLine {\n id: number;\n tokens: IdToken[];\n}\n\n// Module-global, monotonic id counters shared across all Code nodes — ids only\n// need to be unique within a node, but a global counter is the simplest way to\n// guarantee that and never collides.\nlet nextTokenId = 1;\nlet nextLineId = 1;\n\nexport function makeIdToken(content: string, color?: string): IdToken {\n return { id: nextTokenId++, content, color };\n}\n\nexport function makeIdLine(tokens: IdToken[]): IdLine {\n return { id: nextLineId++, tokens };\n}\n\nexport function tokenizeCodeToIdLines(code: string, language: string, theme: CodeTheme): IdLine[] {\n // Until the language parser has loaded (it streams in via the asset loader),\n // fall back to flat, uncolored lines instead of throwing on an unloaded\n // grammar. The node re-tokenizes once the load completes.\n code = normalizeSource(code);\n if (!canHighlight(language, theme)) {\n // Resolved for its warning: an unknown theme is reported whether or not\n // the grammar has landed yet.\n resolveTheme(theme);\n return code.split('\\n').map(line => makeIdLine([makeIdToken(line, '#d1d5db')]));\n }\n return highlightToTokens(code, language, theme).map(line =>\n makeIdLine(line.map(tok => makeIdToken(tok.content, tok.color))),\n );\n}\n\n/**\n * Split `tokens` at character offset `col` (relative to the joined content of\n * the tokens). If `col` falls inside a token, that token is split into two new\n * tokens with fresh ids (the original id is discarded — it didn't exist as a\n * single unit on either side of the cut).\n */\nexport function splitTokensAt(\n tokens: IdToken[],\n col: number,\n): { before: IdToken[]; after: IdToken[] } {\n const before: IdToken[] = [];\n const after: IdToken[] = [];\n let off = 0;\n for (const tok of tokens) {\n const tStart = off;\n const tEnd = off + tok.content.length;\n if (tEnd <= col) {\n before.push(tok);\n } else if (tStart >= col) {\n after.push(tok);\n } else {\n const cut = col - tStart;\n before.push(makeIdToken(tok.content.slice(0, cut), tok.color));\n after.push(makeIdToken(tok.content.slice(cut), tok.color));\n }\n off = tEnd;\n }\n return { before, after };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import type { NormalizedColor } from "@motionscript/sdk";
1
2
  import type { CodeLayout } from "./layout.js";
2
3
  import { IdLine } from "./tokens.js";
3
4
  export interface AnimToken {
@@ -69,7 +70,24 @@ export interface StructuralTransition {
69
70
  fromLayout: CodeLayout | null;
70
71
  toLayout: CodeLayout | null;
71
72
  }
72
- export type CodeTransition = DimTransition | StructuralTransition;
73
+ /** A filled band behind whole rows: the first and last line it covers, by line id so it follows them through an edit, and its paint. */
74
+ export interface RowBand {
75
+ startId: number;
76
+ endId: number;
77
+ color: NormalizedColor;
78
+ radius: number;
79
+ }
80
+ /**
81
+ * One set of row bands becoming another. Bands at the same position in both
82
+ * lists travel and recolour; one with no counterpart fades.
83
+ */
84
+ export interface RowsTransition {
85
+ kind: "rows";
86
+ from: RowBand[];
87
+ to: RowBand[];
88
+ progress: number;
89
+ }
90
+ export type CodeTransition = DimTransition | StructuralTransition | RowsTransition;
73
91
  /**
74
92
  * Decides *when* (in normalized transition time) each part of a structural
75
93
  * edit happens, given only whether the edit removes/adds anything.
@@ -1 +1 @@
1
- {"version":3,"file":"transitions.d.ts","sourceRoot":"","sources":["../src/transitions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transitions.d.ts","sourceRoot":"","sources":["../src/transitions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"transitions.js","sourceRoot":"","sources":["../src/transitions.ts"],"names":[],"mappings":"AA8FA,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,IAAc,EAAE,MAAgB,EAAE,CAAS;IACnE,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACpD,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QAC3D,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,CAA0B,EAAE,CAAS;IAChE,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACjB,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,UAAU,CAAC,CAAS;IAChC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAAU,EAAE,KAA2C;IAC5E,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,UAAmB,EAAE,QAAiB;IAC5D,4EAA4E;IAC5E,yEAAyE;IACzE,4EAA4E;IAC5E,4EAA4E;IAC5E,2BAA2B;IAC3B,IAAI,UAAU,IAAI,QAAQ;QAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IACzF,IAAI,UAAU;QAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACrE,IAAI,QAAQ;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IACnE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAsB,SAAS,CAAC;AAE9D,yHAAyH;AACzH,MAAM,UAAU,YAAY,CAAC,IAAiD;IAC1E,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAC9B,UAAoB,EACpB,WAA6B,EAC7B,mBAAkC,EAClC,cAA2B;IAE3B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE1C,IAAI,mBAAmB,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,mBAAmB,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC5B,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACvE,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK;YAAE,SAAS;QAChC,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAC;AACf,CAAC","sourcesContent":["import type { CodeLayout } from \"./layout\";\nimport { IdLine } from \"./tokens\";\n\n// A single animated token entry owned by one dim transition. Keyed by stable\n// token id rather than (line, tokenIndex) so concurrent animations don't clobber\n// each other when one shifts the indices of tokens the other is animating.\nexport interface AnimToken {\n id: number;\n opacity: number[];\n opacityKeys: number[];\n}\n\n/**\n * A highlight cross-fade: opacity, and nothing else.\n *\n * Structure is untouched, so several of these stack happily and a listing held\n * under a highlight still hits the static-layout cache.\n */\nexport interface DimTransition {\n kind: \"dim\";\n tokens: AnimToken[];\n progress: number;\n}\n\n/**\n * When each part of a structural edit happens, in normalized transition time.\n *\n * The order is what an edit *looks like* being made: what is going away leaves\n * first, what stays reflows into its new place, and only then does what is new\n * appear. Running them together is what made a replacement look like a\n * cross-dissolve of two unrelated listings.\n */\nexport interface Phases {\n /** Removed tokens fade out. Null when the edit removes nothing. */\n out: [number, number] | null;\n /** Surviving tokens travel, and the block resizes. Always present. */\n move: [number, number];\n /** Added tokens fade (and slide) in. Null when the edit adds nothing. */\n in: [number, number] | null;\n}\n\n/**\n * One edit in flight: the structure before, the structure after, and who is\n * doing what.\n *\n * Both endpoints are fixed for the transition's whole life, which is why the\n * two resolved layouts hang off it — they are computed once and reused for\n * every frame the edit spans, rather than rebuilt per frame from a structure\n * that is being mutated underneath.\n */\nexport interface StructuralTransition {\n kind: \"structural\";\n from: IdLine[];\n to: IdLine[];\n removedIds: Set<number>;\n addedIds: Set<number>;\n /**\n * Ids of rows in `to` that did not exist before, and so enter as a whole\n * row rather than as tokens spliced into one.\n *\n * They enter by fading in place, and that is the *only* thing they do. An\n * earlier version slid each one in from the edge the block had just grown\n * along — appended rows rising from below, prepended ones descending, ones\n * spliced into the middle arriving from the left. Every one of those is a\n * claim about where the line came from, and a listing has no such story to\n * tell: text is written where it belongs, it does not travel there. Sliding\n * also puts the row under the neighbours it is meant to sit between for the\n * length of its entrance, which reads as the listing redrawing itself.\n */\n enteringLineIds: Set<number>;\n fromColorById: Map<number, string | undefined>;\n phases: Phases;\n progress: number;\n /** @internal Layout cache — see {@link StructuralTransition}. */\n layoutKey: string | null;\n fromLayout: CodeLayout | null;\n toLayout: CodeLayout | null;\n}\n\nexport type CodeTransition = DimTransition | StructuralTransition;\n\n/**\n * Decides *when* (in normalized transition time) each part of a structural\n * edit happens, given only whether the edit removes/adds anything.\n * `phasesFor` below is the default implementation (exported as\n * `defaultCodePhases`) — pass a `phaseStrategy` of this shape to `<Code>` to\n * replace it with your own timing.\n */\nexport type CodePhaseStrategy = (hasRemoved: boolean, hasAdded: boolean) => Phases;\n\nexport interface TokenState {\n opacity: number;\n}\n\n/** Sample a piecewise-linear curve (keys → values) at progress `p` in [0, 1]. */\nexport function sampleCurve(keys: number[], values: number[], p: number): number {\n if (p <= keys[0]) return values[0];\n if (p >= keys[keys.length - 1]) return values[values.length - 1];\n for (let i = 0; i < keys.length - 1; i++) {\n if (p <= keys[i + 1]) {\n const span = keys[i + 1] - keys[i];\n const local = span === 0 ? 0 : (p - keys[i]) / span;\n return values[i] + (values[i + 1] - values[i]) * local;\n }\n }\n return values[values.length - 1];\n}\n\n/** Progress *within* a phase window, clamped to [0, 1]. A null window is complete. */\nexport function windowProgress(w: [number, number] | null, p: number): number {\n if (!w) return 1;\n const [a, b] = w;\n if (p <= a) return 0;\n if (p >= b) return 1;\n return b === a ? 1 : (p - a) / (b - a);\n}\n\n/** Smooth start and end, so a phase never begins or ends with a velocity step. */\nexport function smoothstep(t: number): number {\n return t * t * (3 - 2 * t);\n}\n\nexport function makeAnim(id: number, curve: { keys: number[]; values: number[] }): AnimToken {\n return { id, opacity: curve.values, opacityKeys: curve.keys };\n}\n\n/**\n * The phase schedule for an edit, shaped by what the edit actually contains.\n *\n * A fixed schedule wastes time it does not need: a pure append has nothing to\n * fade out, so holding the first 40% of the duration empty just makes the\n * animation feel late. Each shape gets the whole duration spent on the parts\n * that exist, with adjacent phases overlapping enough to read as one movement.\n */\nexport function phasesFor(hasRemoved: boolean, hasAdded: boolean): Phases {\n // The overlaps are deliberate and small. Butt-joining the phases leaves the\n // block sitting empty at its new size for a beat between the old content\n // leaving and the new content arriving; letting the arrival start while the\n // reflow's eased tail is still running closes that gap without blurring the\n // order the edit reads in.\n if (hasRemoved && hasAdded) return { out: [0, 0.38], move: [0.10, 0.68], in: [0.52, 1] };\n if (hasRemoved) return { out: [0, 0.45], move: [0.22, 1], in: null };\n if (hasAdded) return { out: null, move: [0, 0.55], in: [0.38, 1] };\n return { out: null, move: [0, 1], in: null };\n}\n\n/** {@link phasesFor} under the name a `phaseStrategy` default is looked up by. */\nexport const defaultCodePhases: CodePhaseStrategy = phasesFor;\n\n/** How far through the \"everything reflows\" phase a frame is, eased. A settled frame (no edit) is always fully moved. */\nexport function moveProgress(edit: { phases: Phases; progress: number } | null): number {\n return edit ? smoothstep(windowProgress(edit.phases.move, edit.progress)) : 1;\n}\n\n/**\n * Resolve the per-token opacity multiplier for the current frame from the\n * persistent highlight dim plus every active dim transition.\n */\nexport function resolveTokenStates(\n tokenLines: IdLine[],\n transitions: CodeTransition[],\n highlightDimOpacity: number | null,\n highlightedIds: Set<number>,\n): Map<number, TokenState> {\n const out = new Map<number, TokenState>();\n\n if (highlightDimOpacity !== null) {\n const dim = highlightDimOpacity;\n for (const line of tokenLines) {\n for (const tok of line.tokens) {\n out.set(tok.id, { opacity: highlightedIds.has(tok.id) ? 1 : dim });\n }\n }\n }\n\n for (const tr of transitions) {\n if (tr.kind !== \"dim\") continue;\n for (const at of tr.tokens) {\n out.set(at.id, { opacity: sampleCurve(at.opacityKeys, at.opacity, tr.progress) });\n }\n }\n\n return out;\n}\n"]}
1
+ {"version":3,"file":"transitions.js","sourceRoot":"","sources":["../src/transitions.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NormalizedColor } from \"@motionscript/sdk\";\nimport type { CodeLayout } from \"./layout\";\nimport { IdLine } from \"./tokens\";\n\n// A single animated token entry owned by one dim transition. Keyed by stable\n// token id rather than (line, tokenIndex) so concurrent animations don't clobber\n// each other when one shifts the indices of tokens the other is animating.\nexport interface AnimToken {\n id: number;\n opacity: number[];\n opacityKeys: number[];\n}\n\n/**\n * A highlight cross-fade: opacity, and nothing else.\n *\n * Structure is untouched, so several of these stack happily and a listing held\n * under a highlight still hits the static-layout cache.\n */\nexport interface DimTransition {\n kind: \"dim\";\n tokens: AnimToken[];\n progress: number;\n}\n\n/**\n * When each part of a structural edit happens, in normalized transition time.\n *\n * The order is what an edit *looks like* being made: what is going away leaves\n * first, what stays reflows into its new place, and only then does what is new\n * appear. Running them together is what made a replacement look like a\n * cross-dissolve of two unrelated listings.\n */\nexport interface Phases {\n /** Removed tokens fade out. Null when the edit removes nothing. */\n out: [number, number] | null;\n /** Surviving tokens travel, and the block resizes. Always present. */\n move: [number, number];\n /** Added tokens fade (and slide) in. Null when the edit adds nothing. */\n in: [number, number] | null;\n}\n\n/**\n * One edit in flight: the structure before, the structure after, and who is\n * doing what.\n *\n * Both endpoints are fixed for the transition's whole life, which is why the\n * two resolved layouts hang off it — they are computed once and reused for\n * every frame the edit spans, rather than rebuilt per frame from a structure\n * that is being mutated underneath.\n */\nexport interface StructuralTransition {\n kind: \"structural\";\n from: IdLine[];\n to: IdLine[];\n removedIds: Set<number>;\n addedIds: Set<number>;\n /**\n * Ids of rows in `to` that did not exist before, and so enter as a whole\n * row rather than as tokens spliced into one.\n *\n * They enter by fading in place, and that is the *only* thing they do. An\n * earlier version slid each one in from the edge the block had just grown\n * along — appended rows rising from below, prepended ones descending, ones\n * spliced into the middle arriving from the left. Every one of those is a\n * claim about where the line came from, and a listing has no such story to\n * tell: text is written where it belongs, it does not travel there. Sliding\n * also puts the row under the neighbours it is meant to sit between for the\n * length of its entrance, which reads as the listing redrawing itself.\n */\n enteringLineIds: Set<number>;\n fromColorById: Map<number, string | undefined>;\n phases: Phases;\n progress: number;\n /** @internal Layout cache — see {@link StructuralTransition}. */\n layoutKey: string | null;\n fromLayout: CodeLayout | null;\n toLayout: CodeLayout | null;\n}\n\n/** A filled band behind whole rows: the first and last line it covers, by line id so it follows them through an edit, and its paint. */\nexport interface RowBand {\n startId: number;\n endId: number;\n color: NormalizedColor;\n radius: number;\n}\n\n/**\n * One set of row bands becoming another. Bands at the same position in both\n * lists travel and recolour; one with no counterpart fades.\n */\nexport interface RowsTransition {\n kind: \"rows\";\n from: RowBand[];\n to: RowBand[];\n progress: number;\n}\n\nexport type CodeTransition = DimTransition | StructuralTransition | RowsTransition;\n\n/**\n * Decides *when* (in normalized transition time) each part of a structural\n * edit happens, given only whether the edit removes/adds anything.\n * `phasesFor` below is the default implementation (exported as\n * `defaultCodePhases`) — pass a `phaseStrategy` of this shape to `<Code>` to\n * replace it with your own timing.\n */\nexport type CodePhaseStrategy = (hasRemoved: boolean, hasAdded: boolean) => Phases;\n\nexport interface TokenState {\n opacity: number;\n}\n\n/** Sample a piecewise-linear curve (keys → values) at progress `p` in [0, 1]. */\nexport function sampleCurve(keys: number[], values: number[], p: number): number {\n if (p <= keys[0]) return values[0];\n if (p >= keys[keys.length - 1]) return values[values.length - 1];\n for (let i = 0; i < keys.length - 1; i++) {\n if (p <= keys[i + 1]) {\n const span = keys[i + 1] - keys[i];\n const local = span === 0 ? 0 : (p - keys[i]) / span;\n return values[i] + (values[i + 1] - values[i]) * local;\n }\n }\n return values[values.length - 1];\n}\n\n/** Progress *within* a phase window, clamped to [0, 1]. A null window is complete. */\nexport function windowProgress(w: [number, number] | null, p: number): number {\n if (!w) return 1;\n const [a, b] = w;\n if (p <= a) return 0;\n if (p >= b) return 1;\n return b === a ? 1 : (p - a) / (b - a);\n}\n\n/** Smooth start and end, so a phase never begins or ends with a velocity step. */\nexport function smoothstep(t: number): number {\n return t * t * (3 - 2 * t);\n}\n\nexport function makeAnim(id: number, curve: { keys: number[]; values: number[] }): AnimToken {\n return { id, opacity: curve.values, opacityKeys: curve.keys };\n}\n\n/**\n * The phase schedule for an edit, shaped by what the edit actually contains.\n *\n * A fixed schedule wastes time it does not need: a pure append has nothing to\n * fade out, so holding the first 40% of the duration empty just makes the\n * animation feel late. Each shape gets the whole duration spent on the parts\n * that exist, with adjacent phases overlapping enough to read as one movement.\n */\nexport function phasesFor(hasRemoved: boolean, hasAdded: boolean): Phases {\n // The overlaps are deliberate and small. Butt-joining the phases leaves the\n // block sitting empty at its new size for a beat between the old content\n // leaving and the new content arriving; letting the arrival start while the\n // reflow's eased tail is still running closes that gap without blurring the\n // order the edit reads in.\n if (hasRemoved && hasAdded) return { out: [0, 0.38], move: [0.10, 0.68], in: [0.52, 1] };\n if (hasRemoved) return { out: [0, 0.45], move: [0.22, 1], in: null };\n if (hasAdded) return { out: null, move: [0, 0.55], in: [0.38, 1] };\n return { out: null, move: [0, 1], in: null };\n}\n\n/** {@link phasesFor} under the name a `phaseStrategy` default is looked up by. */\nexport const defaultCodePhases: CodePhaseStrategy = phasesFor;\n\n/** How far through the \"everything reflows\" phase a frame is, eased. A settled frame (no edit) is always fully moved. */\nexport function moveProgress(edit: { phases: Phases; progress: number } | null): number {\n return edit ? smoothstep(windowProgress(edit.phases.move, edit.progress)) : 1;\n}\n\n/**\n * Resolve the per-token opacity multiplier for the current frame from the\n * persistent highlight dim plus every active dim transition.\n */\nexport function resolveTokenStates(\n tokenLines: IdLine[],\n transitions: CodeTransition[],\n highlightDimOpacity: number | null,\n highlightedIds: Set<number>,\n): Map<number, TokenState> {\n const out = new Map<number, TokenState>();\n\n if (highlightDimOpacity !== null) {\n const dim = highlightDimOpacity;\n for (const line of tokenLines) {\n for (const tok of line.tokens) {\n out.set(tok.id, { opacity: highlightedIds.has(tok.id) ? 1 : dim });\n }\n }\n }\n\n for (const tr of transitions) {\n if (tr.kind !== \"dim\") continue;\n for (const at of tr.tokens) {\n out.set(at.id, { opacity: sampleCurve(at.opacityKeys, at.opacity, tr.progress) });\n }\n }\n\n return out;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motionscript/code",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.0-alpha.10",
4
4
  "type": "module",
5
5
  "description": "Animated, syntax-highlighted code blocks for Motion Script, with token-level append, insert, remove, replace, and highlight transitions.",
6
6
  "repository": {
@@ -16,6 +16,7 @@
16
16
  "types": "dist/index.d.ts",
17
17
  "sideEffects": false,
18
18
  "files": [
19
+ "NOTICE",
19
20
  "dist",
20
21
  "src",
21
22
  "registry.json",
@@ -43,8 +44,9 @@
43
44
  "animation"
44
45
  ],
45
46
  "license": "Apache-2.0",
47
+ "author": "Motionscript",
46
48
  "peerDependencies": {
47
- "@motionscript/core": "^0.1.0-alpha.0"
49
+ "@motionscript/sdk": "^0.1.0-alpha.10"
48
50
  },
49
51
  "dependencies": {
50
52
  "@lezer/common": "^1.5.2",
@@ -72,13 +74,14 @@
72
74
  "typescript": "^6.0.3",
73
75
  "typescript-eslint": "^8.48.0",
74
76
  "vitest": "^4.1.5",
75
- "@motionscript/core": "0.1.0-alpha.0"
77
+ "@motionscript/core": "0.1.0-alpha.10",
78
+ "@motionscript/sdk": "0.1.0-alpha.10"
76
79
  },
77
80
  "scripts": {
78
81
  "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json --resolve-full-paths && node ../../../scripts/build-browser.mjs",
79
82
  "dev": "tsc -p tsconfig.build.json --watch & tsc-alias -p tsconfig.build.json --resolve-full-paths -w",
80
83
  "clean": "rimraf --glob dist .turbo *.tsbuildinfo",
81
- "test": "vitest --passWithNoTests",
84
+ "test": "vitest",
82
85
  "lint": "eslint .",
83
86
  "typecheck": "tsc -p tsconfig.json --noEmit"
84
87
  }
package/src/code-range.ts CHANGED
@@ -49,7 +49,7 @@ export function lines(from: number, to?: number): CodeRange {
49
49
 
50
50
  /**
51
51
  * Immutable, chainable, iterable builder over multiple ranges — mirrors
52
- * {@link FillChain}/`Fills` in `@motionscript/core`. Every method returns a
52
+ * {@link FillChain}/`Fills` in `@motionscript/sdk`. Every method returns a
53
53
  * *new* chain with one more range appended, so the next range-kind method is
54
54
  * called directly rather than through a separate combinator:
55
55
  *
@@ -70,6 +70,15 @@ export class CodeRangeChain {
70
70
  *[Symbol.iterator](): Iterator<CodeRange> {
71
71
  yield* this.list;
72
72
  }
73
+
74
+ /**
75
+ * A chain is stored as its ranges. Without this it serialises as
76
+ * `{ "list": [...] }`, which has no iterator once read back and so selects
77
+ * nothing; a plain array of ranges reads back as the selection it was.
78
+ */
79
+ toJSON(): CodeRange[] {
80
+ return this.list;
81
+ }
73
82
  }
74
83
 
75
84
  /**
package/src/diff.ts CHANGED
@@ -44,6 +44,21 @@ export interface CodeEdit {
44
44
  */
45
45
  const LINE_MATCH_FLOOR = 0.45;
46
46
 
47
+ /**
48
+ * The most line pairs one run of changed lines is scored against each other, and
49
+ * the most across a whole edit.
50
+ *
51
+ * Scoring every pair is quadratic: with 50-character lines it took 31 ms at 200
52
+ * lines and 741 ms at 1,000, paid again for each edit command when it is built.
53
+ * So the lines are first paired where they cannot be in doubt (see
54
+ * {@link alignLines}), and only a run left between two such anchors is scored.
55
+ * A run past the first limit, or what is left of the second, is not compared: its
56
+ * lines leave and enter as whole rows. That is the budget, and an edit that stays
57
+ * inside it is diffed exactly as before.
58
+ */
59
+ export const LINE_ALIGN_CELLS = 40_000;
60
+ export const EDIT_ALIGN_CELLS = 160_000;
61
+
47
62
  /** Weight a token carries when judging similarity: its visible characters. */
48
63
  function tokenWeight(tok: IdToken): number {
49
64
  return tok.content.trim().length;
@@ -158,6 +173,124 @@ function alignTokens(from: IdToken[], to: IdToken[]): Array<[number, number]> {
158
173
  });
159
174
  }
160
175
 
176
+ function sameTokens(a: IdLine, b: IdLine): boolean {
177
+ if (a.tokens.length !== b.tokens.length) return false;
178
+ for (let k = 0; k < a.tokens.length; k++) if (a.tokens[k].content !== b.tokens[k].content) return false;
179
+ return true;
180
+ }
181
+
182
+ /** A line's text, token boundaries included, for telling identical lines apart from similar ones. */
183
+ function signature(line: IdLine): string {
184
+ let out = "";
185
+ for (const tok of line.tokens) out += tok.content + "\u0001";
186
+ return out;
187
+ }
188
+
189
+ /**
190
+ * Pair the lines of two listings, in order.
191
+ *
192
+ * Lines that are the same at the start and at the end are paired outright. In
193
+ * what is left, a line that occurs exactly once on each side is an anchor, and
194
+ * the longest run of anchors that keeps their order splits the rest into runs of
195
+ * changed lines, each scored against itself within the budget (see
196
+ * {@link LINE_ALIGN_CELLS}). A one-line edit to a long listing therefore never
197
+ * builds a table bigger than the lines around it.
198
+ */
199
+ function alignLines(from: IdLine[], to: IdLine[]): Array<[number, number]> {
200
+ const fromSig = from.map(signature);
201
+ const toSig = to.map(signature);
202
+ const pairs: Array<[number, number]> = [];
203
+
204
+ let head = 0;
205
+ while (head < from.length && head < to.length && fromSig[head] === toSig[head]) {
206
+ pairs.push([head, head]);
207
+ head++;
208
+ }
209
+ let tail = 0;
210
+ while (
211
+ tail < from.length - head && tail < to.length - head
212
+ && fromSig[from.length - 1 - tail] === toSig[to.length - 1 - tail]
213
+ ) tail++;
214
+
215
+ const anchors = anchorLines(fromSig, toSig, head, from.length - tail, head, to.length - tail);
216
+ let budget = EDIT_ALIGN_CELLS;
217
+ let fi = head;
218
+ let ti = head;
219
+ for (const [af, at] of [...anchors, [from.length - tail, to.length - tail] as [number, number]]) {
220
+ const rows = af - fi;
221
+ const cols = at - ti;
222
+ const cells = rows * cols;
223
+ if (cells > 0 && cells <= LINE_ALIGN_CELLS && cells <= budget) {
224
+ budget -= cells;
225
+ for (const [i, j] of align(rows, cols, (a, b) => similarity(from[fi + a], to[ti + b]) - LINE_MATCH_FLOOR)) {
226
+ pairs.push([fi + i, ti + j]);
227
+ }
228
+ }
229
+ if (af < from.length - tail) pairs.push([af, at]);
230
+ fi = af + 1;
231
+ ti = at + 1;
232
+ }
233
+ for (let k = tail; k > 0; k--) pairs.push([from.length - k, to.length - k]);
234
+ return pairs;
235
+ }
236
+
237
+ /**
238
+ * The lines that occur once in `from[fa, fb)` and once in `to[ta, tb)`, reduced to
239
+ * the longest subsequence that is increasing on both sides (patience sorting).
240
+ * Blank lines are never anchors: they say nothing about where they belong.
241
+ */
242
+ function anchorLines(
243
+ fromSig: string[],
244
+ toSig: string[],
245
+ fa: number,
246
+ fb: number,
247
+ ta: number,
248
+ tb: number,
249
+ ): Array<[number, number]> {
250
+ const fromAt = new Map<string, number>();
251
+ const seen = new Set<string>();
252
+ for (let i = fa; i < fb; i++) {
253
+ const sig = fromSig[i];
254
+ if (seen.has(sig)) fromAt.delete(sig);
255
+ else fromAt.set(sig, i);
256
+ seen.add(sig);
257
+ }
258
+ const toAt = new Map<string, number>();
259
+ const seenTo = new Set<string>();
260
+ for (let j = ta; j < tb; j++) {
261
+ const sig = toSig[j];
262
+ if (seenTo.has(sig)) toAt.delete(sig);
263
+ else toAt.set(sig, j);
264
+ seenTo.add(sig);
265
+ }
266
+
267
+ // In `to` order, each candidate carries its `from` position.
268
+ const candidates: Array<[number, number]> = [];
269
+ for (let j = ta; j < tb; j++) {
270
+ const i = fromAt.get(toSig[j]);
271
+ if (i !== undefined && toAt.get(toSig[j]) === j && toSig[j].replaceAll("\u0001", "").trim() !== "") {
272
+ candidates.push([i, j]);
273
+ }
274
+ }
275
+
276
+ const tails: number[] = [];
277
+ const previous: number[] = new Array(candidates.length).fill(-1);
278
+ for (let c = 0; c < candidates.length; c++) {
279
+ let lo = 0;
280
+ let hi = tails.length;
281
+ while (lo < hi) {
282
+ const mid = (lo + hi) >> 1;
283
+ if (candidates[tails[mid]][0] < candidates[c][0]) lo = mid + 1;
284
+ else hi = mid;
285
+ }
286
+ if (lo > 0) previous[c] = tails[lo - 1];
287
+ tails[lo] = c;
288
+ }
289
+ const chain: Array<[number, number]> = [];
290
+ for (let c = tails.length > 0 ? tails[tails.length - 1] : -1; c >= 0; c = previous[c]) chain.push(candidates[c]);
291
+ return chain.reverse();
292
+ }
293
+
161
294
  /**
162
295
  * Carry `from`'s identities onto `to`, and report what changed.
163
296
  *
@@ -171,7 +304,7 @@ export function diffCode(from: IdLine[], to: IdLine[]): CodeEdit {
171
304
  const newLineIds = new Set<number>();
172
305
  const fromColorById = new Map<number, string | undefined>();
173
306
 
174
- const linePairs = align(from.length, to.length, (i, j) => similarity(from[i], to[j]) - LINE_MATCH_FLOOR);
307
+ const linePairs = alignLines(from, to);
175
308
 
176
309
  const pairedTo = new Set<number>();
177
310
  const pairedFrom = new Set<number>();
@@ -183,7 +316,9 @@ export function diffCode(from: IdLine[], to: IdLine[]): CodeEdit {
183
316
  const toLine = to[ti];
184
317
  toLine.id = fromLine.id;
185
318
 
186
- const matched = alignTokens(fromLine.tokens, toLine.tokens);
319
+ const matched = sameTokens(fromLine, toLine)
320
+ ? fromLine.tokens.map((_, k): [number, number] => [k, k])
321
+ : alignTokens(fromLine.tokens, toLine.tokens);
187
322
  const keptFrom = new Set<number>();
188
323
  const keptTo = new Set<number>();
189
324
  for (const [a, b] of matched) {
package/src/engine.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  // The Code "engine": syntax highlighting, tokenizing, layout, diffing, and
2
- // transition/phase scheduling — kept separate from node.ts so `ms add code`
3
- // can copy just the node declaration and import this behind
2
+ // transition/phase scheduling — kept separate from node.ts so a copy of the node
3
+ // can take just its declaration and import this behind
4
4
  // `@motionscript/code` instead. What gets copied is whatever this
5
5
  // package's registry.json declares, which for this component is node.ts;
6
- // packages/site/scripts/build-registry.mjs enforces that anything it
6
+ // src/tests/registry.test.ts checks that anything it
7
7
  // reaches for is either copied alongside it or re-exported from here.
8
8
  export * from './transitions';
9
9
  export * from './layout';
10
10
  export { drawCode } from './render';
11
- export type { DrawCodeState } from './render';
11
+ export type { CodeCanvas, DrawCodeState } from './render';
12
12
  export { diffCode as defaultCodeDiff } from './diff';
13
13
  export type { CodeDiffStrategy, CodeEdit } from './diff';
14
- export { loadCodeLanguage, initSyntaxHighlighter, ensureHighlighter, registerCodeTheme, resolveTheme, canHighlight } from './highlight';
14
+ export { loadCodeLanguage, initSyntaxHighlighter, ensureHighlighter, registerCodeTheme, resolveTheme, canHighlight, normalizeSource } from './highlight';
15
15
  export { tokenizeCodeToIdLines } from './tokens';
16
16
  export type { IdLine, IdToken } from './tokens';
17
17
  export { DefaultHighlightStyle, GithubDarkStyle, GithubLightStyle, VscodeDarkStyle, VscodeLightStyle, BUILTIN_THEMES, compileStyle } from './style';