@samva/markup 0.1.0
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/AGENTS.md +8 -0
- package/LICENSE +21 -0
- package/README.md +41 -0
- package/dist/ast-DAhnAvQN.d.ts +120 -0
- package/dist/ast.d.ts +2 -0
- package/dist/ast.js +159 -0
- package/dist/ast.js.map +1 -0
- package/dist/candidate.d.ts +29 -0
- package/dist/candidate.js +88 -0
- package/dist/candidate.js.map +1 -0
- package/dist/checks-CW0nFj5n.js +58922 -0
- package/dist/checks-CW0nFj5n.js.map +1 -0
- package/dist/checks.d.ts +26 -0
- package/dist/checks.js +2 -0
- package/dist/classes.d.ts +27 -0
- package/dist/classes.js +184 -0
- package/dist/classes.js.map +1 -0
- package/dist/compile-sms.d.ts +28 -0
- package/dist/compile-sms.js +44 -0
- package/dist/compile-sms.js.map +1 -0
- package/dist/compile-whatsapp.d.ts +56 -0
- package/dist/compile-whatsapp.js +186 -0
- package/dist/compile-whatsapp.js.map +1 -0
- package/dist/compile.d.ts +93 -0
- package/dist/compile.js +938 -0
- package/dist/compile.js.map +1 -0
- package/dist/components.d.ts +289 -0
- package/dist/components.js +106 -0
- package/dist/components.js.map +1 -0
- package/dist/conditionals.d.ts +10 -0
- package/dist/conditionals.js +42 -0
- package/dist/conditionals.js.map +1 -0
- package/dist/diagnostics-oveE-laV.d.ts +79 -0
- package/dist/diagnostics.d.ts +2 -0
- package/dist/diagnostics.js +62 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/emit.d.ts +50 -0
- package/dist/emit.js +151 -0
- package/dist/emit.js.map +1 -0
- package/dist/footer.d.ts +66 -0
- package/dist/footer.js +90 -0
- package/dist/footer.js.map +1 -0
- package/dist/interpolate.d.ts +27 -0
- package/dist/interpolate.js +61 -0
- package/dist/interpolate.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +10 -0
- package/dist/jsx-dev-runtime.js +7 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime-fSxcvlx4.d.ts +57 -0
- package/dist/jsx-runtime.d.ts +2 -0
- package/dist/jsx-runtime.js +102 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/lexer.d.ts +60 -0
- package/dist/lexer.js +269 -0
- package/dist/lexer.js.map +1 -0
- package/dist/model.d.ts +39 -0
- package/dist/model.js +90 -0
- package/dist/model.js.map +1 -0
- package/dist/ops.d.ts +208 -0
- package/dist/ops.js +546 -0
- package/dist/ops.js.map +1 -0
- package/dist/parser-yzjUOGhc.d.ts +387 -0
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +821 -0
- package/dist/parser.js.map +1 -0
- package/dist/predicate-DTtVtLK7.d.ts +49 -0
- package/dist/predicate.d.ts +2 -0
- package/dist/predicate.js +417 -0
- package/dist/predicate.js.map +1 -0
- package/dist/presets/category-mapping.d.ts +13 -0
- package/dist/presets/category-mapping.js +49 -0
- package/dist/presets/category-mapping.js.map +1 -0
- package/dist/presets/public-gallery.d.ts +490 -0
- package/dist/presets/public-gallery.js +563 -0
- package/dist/presets/public-gallery.js.map +1 -0
- package/dist/presets/public-handoff.d.ts +68 -0
- package/dist/presets/public-handoff.js +105 -0
- package/dist/presets/public-handoff.js.map +1 -0
- package/dist/presets/public-preview-artifacts.d.ts +41 -0
- package/dist/presets/public-preview-artifacts.js +109 -0
- package/dist/presets/public-preview-artifacts.js.map +1 -0
- package/dist/presets/public-preview.d.ts +1168 -0
- package/dist/presets/public-preview.js +1158 -0
- package/dist/presets/public-preview.js.map +1 -0
- package/dist/presets/sources.d.ts +7 -0
- package/dist/presets/sources.js +54 -0
- package/dist/presets/sources.js.map +1 -0
- package/dist/presets.d.ts +350 -0
- package/dist/presets.js +1251 -0
- package/dist/presets.js.map +1 -0
- package/dist/printer.d.ts +6 -0
- package/dist/printer.js +122 -0
- package/dist/printer.js.map +1 -0
- package/dist/registry.d.ts +42 -0
- package/dist/registry.js +646 -0
- package/dist/registry.js.map +1 -0
- package/dist/render-template.d.ts +42 -0
- package/dist/render-template.js +74 -0
- package/dist/render-template.js.map +1 -0
- package/dist/sms-segments-y4FpPilJ.d.ts +13 -0
- package/dist/sms-segments.d.ts +2 -0
- package/dist/sms-segments.js +46 -0
- package/dist/sms-segments.js.map +1 -0
- package/dist/theme-6ApjjiBo.d.ts +116 -0
- package/dist/theme-css.d.ts +24 -0
- package/dist/theme-css.js +509 -0
- package/dist/theme-css.js.map +1 -0
- package/dist/theme.d.ts +2 -0
- package/dist/theme.js +95 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens.d.ts +6 -0
- package/dist/tokens.js +417 -0
- package/dist/tokens.js.map +1 -0
- package/dist/variables-3NGLpNTB.d.ts +77 -0
- package/dist/variables.d.ts +2 -0
- package/dist/variables.js +141 -0
- package/dist/variables.js.map +1 -0
- package/dist/version-BITr58kk.js +96 -0
- package/dist/version-BITr58kk.js.map +1 -0
- package/generated/sml-agent-contract.json +917 -0
- package/generated/sml-email-agent-contract.json +790 -0
- package/generated/sml-email-language-reference.md +160 -0
- package/generated/sml-language-reference.md +220 -0
- package/package.json +203 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.js","names":[],"sources":["../src/lexer.ts"],"sourcesContent":["// Hand-rolled SML lexer, modeled on the TypeScript scanner's JSX mode and\n// sucrase's strict-input discipline: charCode switch dispatch, (kind, start,\n// end) tokens with lazy substring materialization, and two parser-driven scan\n// modes (text between tags, tokens inside tags). Runs per-keystroke in the\n// editor — no regexes, no throw, no allocation beyond the token objects.\n\nconst CHAR_TAB = 9;\nconst CHAR_LINE_FEED = 10;\nconst CHAR_CARRIAGE_RETURN = 13;\nconst CHAR_SPACE = 32;\nconst CHAR_BANG = 33;\nconst CHAR_DOUBLE_QUOTE = 34;\nconst CHAR_HASH = 35;\nconst CHAR_DOLLAR = 36;\nconst CHAR_AMPERSAND = 38;\nconst CHAR_SINGLE_QUOTE = 39;\nconst CHAR_SLASH = 47;\nconst CHAR_SEMICOLON = 59;\nconst CHAR_LESS_THAN = 60;\nconst CHAR_EQUALS = 61;\nconst CHAR_GREATER_THAN = 62;\nconst CHAR_OPEN_BRACE = 123;\nconst CHAR_CLOSE_BRACE = 125;\nconst CHAR_DOT = 46;\nconst CHAR_UNDERSCORE = 95;\nconst CHAR_0 = 48;\nconst CHAR_9 = 57;\nconst CHAR_UPPER_A = 65;\nconst CHAR_UPPER_Z = 90;\nconst CHAR_LOWER_A = 97;\nconst CHAR_LOWER_X = 120;\nconst CHAR_LOWER_Z = 122;\n\nexport const TokenKind = {\n EndOfFile: 0,\n /** `<` opening a start tag (text mode). */\n LessThan: 1,\n /** `</` opening a close tag (text mode). */\n LessThanSlash: 2,\n GreaterThan: 3,\n SlashGreaterThan: 4,\n Identifier: 5,\n Equals: 6,\n /** Quoted attribute value; getStringValue decodes entities. */\n String: 7,\n OpenBrace: 8,\n CloseBrace: 9,\n /** Unsigned integer inside a brace attribute value. */\n Number: 10,\n /** Raw text run; getTextValue decodes entities. */\n Text: 11,\n /** `{{name}}` or `${name}`; name/syntax carried on the token. */\n Interpolation: 12,\n /** Lexically invalid input; error carried on the token. */\n Unknown: 13,\n} as const;\n\nexport type TokenKind = (typeof TokenKind)[keyof typeof TokenKind];\n\nexport interface TokenError {\n readonly code: string;\n readonly message: string;\n}\n\nexport interface Token {\n readonly kind: TokenKind;\n readonly start: number;\n readonly end: number;\n /** Interpolation only. */\n readonly name?: string | undefined;\n /** Interpolation only. */\n readonly syntax?: \"curly\" | \"dollar\" | undefined;\n /** Unknown only. */\n readonly error?: TokenError | undefined;\n}\n\nconst isWhitespace = (code: number): boolean =>\n code === CHAR_SPACE ||\n code === CHAR_TAB ||\n code === CHAR_LINE_FEED ||\n code === CHAR_CARRIAGE_RETURN;\n\nconst isDigit = (code: number): boolean => code >= CHAR_0 && code <= CHAR_9;\n\nconst isLetter = (code: number): boolean =>\n (code >= CHAR_UPPER_A && code <= CHAR_UPPER_Z) || (code >= CHAR_LOWER_A && code <= CHAR_LOWER_Z);\n\nconst isNameChar = (code: number): boolean =>\n isLetter(code) || isDigit(code) || code === CHAR_UNDERSCORE || code === CHAR_DOT;\n\nconst NAMED_ENTITIES: Readonly<Record<string, string>> = {\n amp: \"&\",\n lt: \"<\",\n gt: \">\",\n quot: '\"',\n apos: \"'\",\n nbsp: \" \",\n};\n\n/**\n * Validates the entity starting at `offset` (which points at `&`).\n * Returns the end offset (past `;`) or -1 when malformed.\n */\nconst scanEntity = (source: string, offset: number): number => {\n let index = offset + 1;\n if (source.charCodeAt(index) === CHAR_HASH) {\n index++;\n const hex = source.charCodeAt(index) === CHAR_LOWER_X;\n if (hex) index++;\n const digitsStart = index;\n while (index < source.length) {\n const code = source.charCodeAt(index);\n const isHexDigit =\n isDigit(code) || (hex && ((code >= 97 && code <= 102) || (code >= 65 && code <= 70)));\n if (!isHexDigit) break;\n index++;\n }\n if (index === digitsStart) return -1;\n return source.charCodeAt(index) === CHAR_SEMICOLON ? index + 1 : -1;\n }\n const nameStart = index;\n while (index < source.length && isLetter(source.charCodeAt(index))) index++;\n const name = source.slice(nameStart, index);\n if (!(name in NAMED_ENTITIES)) return -1;\n return source.charCodeAt(index) === CHAR_SEMICOLON ? index + 1 : -1;\n};\n\n/** Decodes entities in text that already passed `scanEntity` validation. */\nexport const decodeEntities = (raw: string): string => {\n if (!raw.includes(\"&\")) return raw;\n let result = \"\";\n let index = 0;\n while (index < raw.length) {\n const ampersand = raw.indexOf(\"&\", index);\n if (ampersand === -1) {\n result += raw.slice(index);\n break;\n }\n result += raw.slice(index, ampersand);\n const semicolon = raw.indexOf(\";\", ampersand);\n if (semicolon === -1) {\n // No terminating ';' — the scanner rejects unterminated entities before\n // this runs, but never rely on that here: emit the rest literally\n // instead of resetting the cursor into an infinite loop.\n result += raw.slice(ampersand);\n break;\n }\n const body = raw.slice(ampersand + 1, semicolon);\n if (body.startsWith(\"#x\") || body.startsWith(\"#X\")) {\n result += String.fromCodePoint(Number.parseInt(body.slice(2), 16));\n } else if (body.startsWith(\"#\")) {\n result += String.fromCodePoint(Number.parseInt(body.slice(1), 10));\n } else {\n result += NAMED_ENTITIES[body]!;\n }\n index = semicolon + 1;\n }\n return result;\n};\n\nexport interface Lexer {\n /** Current scan position (start of the next token). */\n readonly position: () => number;\n /** Scan one token in text mode (between tags). */\n readonly scanTextToken: () => Token;\n /** Scan one token in tag mode (inside `<...>`), skipping whitespace. */\n readonly scanTagToken: () => Token;\n /** Lazy raw source slice for a token. */\n readonly getText: (token: Token) => string;\n /** Entity-decoded value of a Text token. */\n readonly getTextValue: (token: Token) => string;\n /** Entity-decoded contents of a String token (without quotes). */\n readonly getStringValue: (token: Token) => string;\n}\n\nexport const createLexer = (source: string): Lexer => {\n let position = 0;\n const length = source.length;\n\n const token = (kind: TokenKind, start: number, extra?: Partial<Token>): Token => {\n const created: Token = { kind, start, end: position, ...extra };\n return created;\n };\n\n const unknown = (start: number, code: string, message: string): Token => {\n if (position === start) position = Math.min(start + 1, length);\n return token(TokenKind.Unknown, start, { error: { code, message } });\n };\n\n const scanInterpolation = (start: number, syntax: \"curly\" | \"dollar\"): Token => {\n // Preserves today's interpolation grammar exactly (packages/document\n // variables.ts): {{ name }} and ${ /name } with optional inner whitespace,\n // names of [\\w.]+, and a tolerated leading slash in the dollar form.\n position = start + 2;\n while (position < length && isWhitespace(source.charCodeAt(position))) position++;\n if (syntax === \"dollar\" && source.charCodeAt(position) === CHAR_SLASH) position++;\n const nameStart = position;\n while (position < length && isNameChar(source.charCodeAt(position))) position++;\n const name = source.slice(nameStart, position);\n while (position < length && isWhitespace(source.charCodeAt(position))) position++;\n const closed =\n syntax === \"curly\"\n ? source.charCodeAt(position) === CHAR_CLOSE_BRACE &&\n source.charCodeAt(position + 1) === CHAR_CLOSE_BRACE\n : source.charCodeAt(position) === CHAR_CLOSE_BRACE;\n if (name.length === 0 || !closed) {\n position = start;\n const example = syntax === \"curly\" ? \"{{variableName}}\" : \"${variableName}\";\n return unknown(\n start,\n \"invalid-interpolation\",\n `malformed interpolation — write ${example} using letters, digits, underscore, or dot`,\n );\n }\n position += syntax === \"curly\" ? 2 : 1;\n return token(TokenKind.Interpolation, start, { name, syntax });\n };\n\n const scanTextToken = (): Token => {\n const start = position;\n if (position >= length) return token(TokenKind.EndOfFile, start);\n\n const first = source.charCodeAt(position);\n if (first === CHAR_LESS_THAN) {\n const next = source.charCodeAt(position + 1);\n if (next === CHAR_SLASH) {\n position += 2;\n return token(TokenKind.LessThanSlash, start);\n }\n if (isLetter(next)) {\n position += 1;\n return token(TokenKind.LessThan, start);\n }\n if (next === CHAR_BANG) {\n return unknown(\n start,\n \"comment-not-supported\",\n source.startsWith(\"<!--\", position)\n ? \"comments are not part of SML — remove the <!-- ... --> block\"\n : \"unexpected <! — SML has no doctype or declaration syntax; remove it\",\n );\n }\n return unknown(start, \"stray-angle-bracket\", \"stray < in text — escape it as <\");\n }\n if (first === CHAR_OPEN_BRACE && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) {\n return scanInterpolation(start, \"curly\");\n }\n if (first === CHAR_DOLLAR && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) {\n return scanInterpolation(start, \"dollar\");\n }\n\n // Plain text run: stop at `<`, `{{`, `${`, or EOF. Validate entities inline\n // so malformed `&` gets a precise span.\n while (position < length) {\n const code = source.charCodeAt(position);\n if (code === CHAR_LESS_THAN) break;\n if (code === CHAR_OPEN_BRACE && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) break;\n if (code === CHAR_DOLLAR && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) break;\n if (code === CHAR_AMPERSAND) {\n const entityEnd = scanEntity(source, position);\n if (entityEnd === -1) {\n if (position > start) return token(TokenKind.Text, start);\n return unknown(\n start,\n \"bare-ampersand\",\n \"bare & in text — escape it as & (or use a supported entity like <)\",\n );\n }\n position = entityEnd;\n continue;\n }\n position++;\n }\n return token(TokenKind.Text, start);\n };\n\n const scanTagToken = (): Token => {\n while (position < length && isWhitespace(source.charCodeAt(position))) position++;\n const start = position;\n if (position >= length) return token(TokenKind.EndOfFile, start);\n\n const code = source.charCodeAt(position);\n switch (code) {\n case CHAR_GREATER_THAN:\n position++;\n return token(TokenKind.GreaterThan, start);\n case CHAR_SLASH:\n if (source.charCodeAt(position + 1) === CHAR_GREATER_THAN) {\n position += 2;\n return token(TokenKind.SlashGreaterThan, start);\n }\n return unknown(\n start,\n \"unexpected-character\",\n \"unexpected / inside tag — write /> to self-close\",\n );\n case CHAR_EQUALS:\n position++;\n return token(TokenKind.Equals, start);\n case CHAR_OPEN_BRACE:\n position++;\n return token(TokenKind.OpenBrace, start);\n case CHAR_CLOSE_BRACE:\n position++;\n return token(TokenKind.CloseBrace, start);\n case CHAR_DOUBLE_QUOTE:\n case CHAR_SINGLE_QUOTE: {\n position++;\n while (position < length) {\n const current = source.charCodeAt(position);\n if (current === code) break;\n if (current === CHAR_AMPERSAND) {\n const entityEnd = scanEntity(source, position);\n if (entityEnd === -1) {\n return unknown(\n position,\n \"bare-ampersand\",\n \"bare & in attribute value — escape it as &\",\n );\n }\n position = entityEnd;\n continue;\n }\n if (current === CHAR_LESS_THAN || current === CHAR_LINE_FEED) break;\n position++;\n }\n if (source.charCodeAt(position) !== code) {\n const quote = String.fromCharCode(code);\n return {\n kind: TokenKind.Unknown,\n start,\n end: position,\n error: {\n code: \"unterminated-string\",\n message: `unterminated attribute value — add a closing ${quote}`,\n },\n };\n }\n position++;\n return token(TokenKind.String, start);\n }\n default: {\n if (isLetter(code)) {\n position++;\n while (position < length) {\n const current = source.charCodeAt(position);\n if (!isLetter(current) && !isDigit(current)) break;\n position++;\n }\n return token(TokenKind.Identifier, start);\n }\n if (isDigit(code)) {\n position++;\n while (position < length && isDigit(source.charCodeAt(position))) position++;\n return token(TokenKind.Number, start);\n }\n return unknown(\n start,\n \"unexpected-character\",\n `unexpected character ${JSON.stringify(String.fromCharCode(code))} inside tag`,\n );\n }\n }\n };\n\n return {\n position: () => position,\n scanTextToken,\n scanTagToken,\n getText: (t) => source.slice(t.start, t.end),\n getTextValue: (t) => decodeEntities(source.slice(t.start, t.end)),\n getStringValue: (t) => decodeEntities(source.slice(t.start + 1, t.end - 1)),\n };\n};\n"],"mappings":"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"}
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { C as SmlDocument, D as SmlTag } from "./ast-DAhnAvQN.js";
|
|
2
|
+
import { Result, Schema } from "effect";
|
|
3
|
+
//#region src/model.d.ts
|
|
4
|
+
declare const SmlNodeKeyAttrsSchema: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Finite]>>;
|
|
5
|
+
declare const SmlNodeIndexEntrySchema: Schema.Struct<{
|
|
6
|
+
readonly id: Schema.String;
|
|
7
|
+
readonly tag: Schema.String;
|
|
8
|
+
readonly order: Schema.Finite;
|
|
9
|
+
readonly parentId: Schema.NullOr<Schema.String>;
|
|
10
|
+
readonly childIndex: Schema.Finite;
|
|
11
|
+
readonly depth: Schema.Finite;
|
|
12
|
+
readonly path: Schema.String;
|
|
13
|
+
readonly textPreview: Schema.String;
|
|
14
|
+
readonly attrs: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Finite]>>;
|
|
15
|
+
}>;
|
|
16
|
+
type SmlNodeIndexEntry = typeof SmlNodeIndexEntrySchema.Type & {
|
|
17
|
+
readonly tag: SmlTag;
|
|
18
|
+
};
|
|
19
|
+
declare const SmlNodeIndexSchema: Schema.Struct<{
|
|
20
|
+
readonly nodes: Schema.$Array<Schema.Struct<{
|
|
21
|
+
readonly id: Schema.String;
|
|
22
|
+
readonly tag: Schema.String;
|
|
23
|
+
readonly order: Schema.Finite;
|
|
24
|
+
readonly parentId: Schema.NullOr<Schema.String>;
|
|
25
|
+
readonly childIndex: Schema.Finite;
|
|
26
|
+
readonly depth: Schema.Finite;
|
|
27
|
+
readonly path: Schema.String;
|
|
28
|
+
readonly textPreview: Schema.String;
|
|
29
|
+
readonly attrs: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Finite]>>;
|
|
30
|
+
}>>;
|
|
31
|
+
}>;
|
|
32
|
+
type SmlNodeIndex = typeof SmlNodeIndexSchema.Type & {
|
|
33
|
+
readonly nodes: readonly SmlNodeIndexEntry[];
|
|
34
|
+
};
|
|
35
|
+
declare const deriveNodeIndexFromDocument: (document: SmlDocument) => SmlNodeIndex;
|
|
36
|
+
declare const deriveNodeIndex: (source: string) => Result.Result<SmlNodeIndex, string>;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { SmlNodeIndex, SmlNodeIndexEntry, SmlNodeIndexEntrySchema, SmlNodeIndexSchema, SmlNodeKeyAttrsSchema, deriveNodeIndex, deriveNodeIndexFromDocument };
|
|
39
|
+
//# sourceMappingURL=model.d.ts.map
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { parseSml } from "./parser.js";
|
|
2
|
+
import { Result, Schema } from "effect";
|
|
3
|
+
//#region src/model.ts
|
|
4
|
+
const SmlNodeKeyAttrsSchema = Schema.Record(Schema.String, Schema.Union([Schema.String, Schema.Finite]));
|
|
5
|
+
const SmlNodeIndexEntrySchema = Schema.Struct({
|
|
6
|
+
id: Schema.String,
|
|
7
|
+
tag: Schema.String,
|
|
8
|
+
order: Schema.Finite,
|
|
9
|
+
parentId: Schema.NullOr(Schema.String),
|
|
10
|
+
childIndex: Schema.Finite,
|
|
11
|
+
depth: Schema.Finite,
|
|
12
|
+
path: Schema.String,
|
|
13
|
+
textPreview: Schema.String,
|
|
14
|
+
attrs: SmlNodeKeyAttrsSchema
|
|
15
|
+
});
|
|
16
|
+
const SmlNodeIndexSchema = Schema.Struct({ nodes: Schema.Array(SmlNodeIndexEntrySchema) });
|
|
17
|
+
const KEY_ATTRS = /* @__PURE__ */ new Set([
|
|
18
|
+
"alt",
|
|
19
|
+
"class",
|
|
20
|
+
"dir",
|
|
21
|
+
"height",
|
|
22
|
+
"hidden",
|
|
23
|
+
"href",
|
|
24
|
+
"label",
|
|
25
|
+
"lang",
|
|
26
|
+
"level",
|
|
27
|
+
"name",
|
|
28
|
+
"scheme",
|
|
29
|
+
"src",
|
|
30
|
+
"test",
|
|
31
|
+
"valign",
|
|
32
|
+
"width"
|
|
33
|
+
]);
|
|
34
|
+
const attrValue = (value) => value.value;
|
|
35
|
+
const truncate = (value, length) => value.length <= length ? value : `${value.slice(0, length - 3)}...`;
|
|
36
|
+
const normalizePreview = (value) => truncate(value.replace(/\s+/g, " ").trim(), 96);
|
|
37
|
+
const textPreview = (node) => {
|
|
38
|
+
const parts = [];
|
|
39
|
+
const visit = (child) => {
|
|
40
|
+
if (child.kind === "text") {
|
|
41
|
+
parts.push(child.value);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (child.kind === "interpolation") {
|
|
45
|
+
parts.push(`{{${child.name}}}`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const nested of child.children) visit(nested);
|
|
49
|
+
};
|
|
50
|
+
for (const child of node.children) visit(child);
|
|
51
|
+
return normalizePreview(parts.join(" "));
|
|
52
|
+
};
|
|
53
|
+
const keyAttrs = (node) => Object.fromEntries(node.attributes.filter((attribute) => KEY_ATTRS.has(attribute.name)).map((attribute) => [attribute.name, attrValue(attribute.value)]));
|
|
54
|
+
const deriveNodeIndexFromDocument = (document) => {
|
|
55
|
+
const nodes = [];
|
|
56
|
+
let order = 0;
|
|
57
|
+
const visit = (node, parentId, childIndex, depth, parentPath) => {
|
|
58
|
+
if (node.kind !== "element") return;
|
|
59
|
+
if (node.tag === "Source") return;
|
|
60
|
+
const pathSegment = `${node.tag}[${childIndex}]`;
|
|
61
|
+
const path = parentPath ? `${parentPath}/${pathSegment}` : pathSegment;
|
|
62
|
+
nodes.push({
|
|
63
|
+
id: node.id,
|
|
64
|
+
tag: node.tag,
|
|
65
|
+
order: order++,
|
|
66
|
+
parentId,
|
|
67
|
+
childIndex,
|
|
68
|
+
depth,
|
|
69
|
+
path,
|
|
70
|
+
textPreview: textPreview(node),
|
|
71
|
+
attrs: keyAttrs(node)
|
|
72
|
+
});
|
|
73
|
+
let elementChildIndex = 0;
|
|
74
|
+
for (const child of node.children) if (child.kind === "element") {
|
|
75
|
+
visit(child, node.id, elementChildIndex, depth + 1, path);
|
|
76
|
+
elementChildIndex++;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
visit(document.root, null, 0, 0, "");
|
|
80
|
+
return { nodes };
|
|
81
|
+
};
|
|
82
|
+
const deriveNodeIndex = (source) => {
|
|
83
|
+
const parsed = parseSml(source);
|
|
84
|
+
if (Result.isFailure(parsed)) return Result.fail(parsed.failure.diagnostics.map((diagnostic) => diagnostic.message).join("\n"));
|
|
85
|
+
return Result.succeed(deriveNodeIndexFromDocument(parsed.success));
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { SmlNodeIndexEntrySchema, SmlNodeIndexSchema, SmlNodeKeyAttrsSchema, deriveNodeIndex, deriveNodeIndexFromDocument };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","names":[],"sources":["../src/model.ts"],"sourcesContent":["import { Result, Schema } from \"effect\";\n\nimport type { AttributeValue, ElementNode, SmlDocument, SmlNode, SmlTag } from \"./ast\";\nimport { parseSml } from \"./parser\";\n\nexport const SmlNodeKeyAttrsSchema = Schema.Record(\n Schema.String,\n Schema.Union([Schema.String, Schema.Finite]),\n);\n\nexport const SmlNodeIndexEntrySchema = Schema.Struct({\n id: Schema.String,\n tag: Schema.String,\n order: Schema.Finite,\n parentId: Schema.NullOr(Schema.String),\n childIndex: Schema.Finite,\n depth: Schema.Finite,\n path: Schema.String,\n textPreview: Schema.String,\n attrs: SmlNodeKeyAttrsSchema,\n});\n\nexport type SmlNodeIndexEntry = typeof SmlNodeIndexEntrySchema.Type & {\n readonly tag: SmlTag;\n};\n\nexport const SmlNodeIndexSchema = Schema.Struct({\n nodes: Schema.Array(SmlNodeIndexEntrySchema),\n});\n\nexport type SmlNodeIndex = typeof SmlNodeIndexSchema.Type & {\n readonly nodes: readonly SmlNodeIndexEntry[];\n};\n\nconst KEY_ATTRS = new Set([\n \"alt\",\n \"class\",\n \"dir\",\n \"height\",\n \"hidden\",\n \"href\",\n \"label\",\n \"lang\",\n \"level\",\n \"name\",\n \"scheme\",\n \"src\",\n \"test\",\n \"valign\",\n \"width\",\n]);\n\nconst attrValue = (value: AttributeValue): string | number => value.value;\n\nconst truncate = (value: string, length: number): string =>\n value.length <= length ? value : `${value.slice(0, length - 3)}...`;\n\nconst normalizePreview = (value: string): string => truncate(value.replace(/\\s+/g, \" \").trim(), 96);\n\nconst textPreview = (node: ElementNode): string => {\n const parts: string[] = [];\n const visit = (child: SmlNode): void => {\n if (child.kind === \"text\") {\n parts.push(child.value);\n return;\n }\n if (child.kind === \"interpolation\") {\n parts.push(`{{${child.name}}}`);\n return;\n }\n for (const nested of child.children) visit(nested);\n };\n for (const child of node.children) visit(child);\n return normalizePreview(parts.join(\" \"));\n};\n\nconst keyAttrs = (node: ElementNode): Readonly<Record<string, string | number>> =>\n Object.fromEntries(\n node.attributes\n .filter((attribute) => KEY_ATTRS.has(attribute.name))\n .map((attribute) => [attribute.name, attrValue(attribute.value)]),\n );\n\nexport const deriveNodeIndexFromDocument = (document: SmlDocument): SmlNodeIndex => {\n const nodes: SmlNodeIndexEntry[] = [];\n let order = 0;\n\n const visit = (\n node: SmlNode,\n parentId: string | null,\n childIndex: number,\n depth: number,\n parentPath: string,\n ): void => {\n if (node.kind !== \"element\") return;\n if (node.tag === \"Source\") return;\n\n const pathSegment = `${node.tag}[${childIndex}]`;\n const path = parentPath ? `${parentPath}/${pathSegment}` : pathSegment;\n nodes.push({\n id: node.id,\n tag: node.tag,\n order: order++,\n parentId,\n childIndex,\n depth,\n path,\n textPreview: textPreview(node),\n attrs: keyAttrs(node),\n });\n\n let elementChildIndex = 0;\n for (const child of node.children) {\n if (child.kind === \"element\") {\n visit(child, node.id, elementChildIndex, depth + 1, path);\n elementChildIndex++;\n }\n }\n };\n\n visit(document.root, null, 0, 0, \"\");\n return { nodes };\n};\n\nexport const deriveNodeIndex = (source: string): Result.Result<SmlNodeIndex, string> => {\n const parsed = parseSml(source);\n if (Result.isFailure(parsed)) {\n return Result.fail(\n parsed.failure.diagnostics.map((diagnostic) => diagnostic.message).join(\"\\n\"),\n );\n }\n return Result.succeed(deriveNodeIndexFromDocument(parsed.success));\n};\n"],"mappings":";;;AAKA,MAAa,wBAAwB,OAAO,OAC1C,OAAO,QACP,OAAO,MAAM,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC,CAC7C;AAEA,MAAa,0BAA0B,OAAO,OAAO;CACnD,IAAI,OAAO;CACX,KAAK,OAAO;CACZ,OAAO,OAAO;CACd,UAAU,OAAO,OAAO,OAAO,MAAM;CACrC,YAAY,OAAO;CACnB,OAAO,OAAO;CACd,MAAM,OAAO;CACb,aAAa,OAAO;CACpB,OAAO;AACT,CAAC;AAMD,MAAa,qBAAqB,OAAO,OAAO,EAC9C,OAAO,OAAO,MAAM,uBAAuB,EAC7C,CAAC;AAMD,MAAM,4BAAY,IAAI,IAAI;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,aAAa,UAA2C,MAAM;AAEpE,MAAM,YAAY,OAAe,WAC/B,MAAM,UAAU,SAAS,QAAQ,GAAG,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE;AAEjE,MAAM,oBAAoB,UAA0B,SAAS,MAAM,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;AAElG,MAAM,eAAe,SAA8B;CACjD,MAAM,QAAkB,CAAC;CACzB,MAAM,SAAS,UAAyB;EACtC,IAAI,MAAM,SAAS,QAAQ;GACzB,MAAM,KAAK,MAAM,KAAK;GACtB;EACF;EACA,IAAI,MAAM,SAAS,iBAAiB;GAClC,MAAM,KAAK,KAAK,MAAM,KAAK,GAAG;GAC9B;EACF;EACA,KAAK,MAAM,UAAU,MAAM,UAAU,MAAM,MAAM;CACnD;CACA,KAAK,MAAM,SAAS,KAAK,UAAU,MAAM,KAAK;CAC9C,OAAO,iBAAiB,MAAM,KAAK,GAAG,CAAC;AACzC;AAEA,MAAM,YAAY,SAChB,OAAO,YACL,KAAK,WACF,QAAQ,cAAc,UAAU,IAAI,UAAU,IAAI,CAAC,CAAC,CACpD,KAAK,cAAc,CAAC,UAAU,MAAM,UAAU,UAAU,KAAK,CAAC,CAAC,CACpE;AAEF,MAAa,+BAA+B,aAAwC;CAClF,MAAM,QAA6B,CAAC;CACpC,IAAI,QAAQ;CAEZ,MAAM,SACJ,MACA,UACA,YACA,OACA,eACS;EACT,IAAI,KAAK,SAAS,WAAW;EAC7B,IAAI,KAAK,QAAQ,UAAU;EAE3B,MAAM,cAAc,GAAG,KAAK,IAAI,GAAG,WAAW;EAC9C,MAAM,OAAO,aAAa,GAAG,WAAW,GAAG,gBAAgB;EAC3D,MAAM,KAAK;GACT,IAAI,KAAK;GACT,KAAK,KAAK;GACV,OAAO;GACP;GACA;GACA;GACA;GACA,aAAa,YAAY,IAAI;GAC7B,OAAO,SAAS,IAAI;EACtB,CAAC;EAED,IAAI,oBAAoB;EACxB,KAAK,MAAM,SAAS,KAAK,UACvB,IAAI,MAAM,SAAS,WAAW;GAC5B,MAAM,OAAO,KAAK,IAAI,mBAAmB,QAAQ,GAAG,IAAI;GACxD;EACF;CAEJ;CAEA,MAAM,SAAS,MAAM,MAAM,GAAG,GAAG,EAAE;CACnC,OAAO,EAAE,MAAM;AACjB;AAEA,MAAa,mBAAmB,WAAwD;CACtF,MAAM,SAAS,SAAS,MAAM;CAC9B,IAAI,OAAO,UAAU,MAAM,GACzB,OAAO,OAAO,KACZ,OAAO,QAAQ,YAAY,KAAK,eAAe,WAAW,OAAO,CAAC,CAAC,KAAK,IAAI,CAC9E;CAEF,OAAO,OAAO,QAAQ,4BAA4B,OAAO,OAAO,CAAC;AACnE"}
|
package/dist/ops.d.ts
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { o as SmlParseError } from "./diagnostics-oveE-laV.js";
|
|
2
|
+
import { T as SmlNode } from "./ast-DAhnAvQN.js";
|
|
3
|
+
import { Result, Schema } from "effect";
|
|
4
|
+
//#region src/ops.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* A single edit against SML source. `nodeId` (and `referenceId` /
|
|
7
|
+
* `targetParentId`) are positional ids from the source the caller last read;
|
|
8
|
+
* within a batch they always resolve against that snapshot — see {@link applyOps}.
|
|
9
|
+
*/
|
|
10
|
+
declare const SmlOpSchema: Schema.Union<readonly [Schema.TaggedStruct<"setProp", {
|
|
11
|
+
readonly nodeId: Schema.String;
|
|
12
|
+
readonly name: Schema.String;
|
|
13
|
+
readonly value: Schema.NullOr<Schema.Union<readonly [Schema.Struct<{
|
|
14
|
+
readonly kind: Schema.Literal<"string">;
|
|
15
|
+
readonly value: Schema.String;
|
|
16
|
+
}>, Schema.Struct<{
|
|
17
|
+
readonly kind: Schema.Literal<"number">;
|
|
18
|
+
readonly value: Schema.Finite;
|
|
19
|
+
}>]>>;
|
|
20
|
+
}>, Schema.TaggedStruct<"setChildren", {
|
|
21
|
+
readonly nodeId: Schema.String;
|
|
22
|
+
readonly children: Schema.$Array<Schema.Codec<SmlNode, SmlNode, never, never>>;
|
|
23
|
+
}>, Schema.TaggedStruct<"insertBlock", {
|
|
24
|
+
readonly tag: Schema.Literals<readonly ["Email", "Subject", "Preview", "Container", "Section", "Row", "Column", "Heading", "Text", "Button", "Image", "Divider", "Spacer", "List", "ListItem", "If", "Else", "strong", "em", "a", "Source", "Sms", "WhatsApp", "Header", "Body", "Footer", "Buttons"]>;
|
|
25
|
+
readonly referenceId: Schema.NullOr<Schema.String>;
|
|
26
|
+
readonly position: Schema.Literals<readonly ["before", "after", "inside"]>;
|
|
27
|
+
}>, Schema.TaggedStruct<"insertSnippet", {
|
|
28
|
+
readonly snippet: Schema.String;
|
|
29
|
+
readonly referenceId: Schema.NullOr<Schema.String>;
|
|
30
|
+
readonly position: Schema.Literals<readonly ["before", "after", "inside"]>;
|
|
31
|
+
}>, Schema.TaggedStruct<"moveNode", {
|
|
32
|
+
readonly nodeId: Schema.String;
|
|
33
|
+
readonly targetParentId: Schema.String;
|
|
34
|
+
readonly insertionIndex: Schema.Finite;
|
|
35
|
+
}>, Schema.TaggedStruct<"duplicateNode", {
|
|
36
|
+
readonly nodeId: Schema.String;
|
|
37
|
+
}>, Schema.TaggedStruct<"removeNode", {
|
|
38
|
+
readonly nodeId: Schema.String;
|
|
39
|
+
}>]>;
|
|
40
|
+
type SmlOp = typeof SmlOpSchema.Type;
|
|
41
|
+
declare const SmlOpResultSchema: Schema.Struct<{
|
|
42
|
+
readonly index: Schema.Finite;
|
|
43
|
+
readonly status: Schema.Literals<readonly ["applied", "failed"]>;
|
|
44
|
+
readonly op: Schema.Union<readonly [Schema.TaggedStruct<"setProp", {
|
|
45
|
+
readonly nodeId: Schema.String;
|
|
46
|
+
readonly name: Schema.String;
|
|
47
|
+
readonly value: Schema.NullOr<Schema.Union<readonly [Schema.Struct<{
|
|
48
|
+
readonly kind: Schema.Literal<"string">;
|
|
49
|
+
readonly value: Schema.String;
|
|
50
|
+
}>, Schema.Struct<{
|
|
51
|
+
readonly kind: Schema.Literal<"number">;
|
|
52
|
+
readonly value: Schema.Finite;
|
|
53
|
+
}>]>>;
|
|
54
|
+
}>, Schema.TaggedStruct<"setChildren", {
|
|
55
|
+
readonly nodeId: Schema.String;
|
|
56
|
+
readonly children: Schema.$Array<Schema.Codec<SmlNode, SmlNode, never, never>>;
|
|
57
|
+
}>, Schema.TaggedStruct<"insertBlock", {
|
|
58
|
+
readonly tag: Schema.Literals<readonly ["Email", "Subject", "Preview", "Container", "Section", "Row", "Column", "Heading", "Text", "Button", "Image", "Divider", "Spacer", "List", "ListItem", "If", "Else", "strong", "em", "a", "Source", "Sms", "WhatsApp", "Header", "Body", "Footer", "Buttons"]>;
|
|
59
|
+
readonly referenceId: Schema.NullOr<Schema.String>;
|
|
60
|
+
readonly position: Schema.Literals<readonly ["before", "after", "inside"]>;
|
|
61
|
+
}>, Schema.TaggedStruct<"insertSnippet", {
|
|
62
|
+
readonly snippet: Schema.String;
|
|
63
|
+
readonly referenceId: Schema.NullOr<Schema.String>;
|
|
64
|
+
readonly position: Schema.Literals<readonly ["before", "after", "inside"]>;
|
|
65
|
+
}>, Schema.TaggedStruct<"moveNode", {
|
|
66
|
+
readonly nodeId: Schema.String;
|
|
67
|
+
readonly targetParentId: Schema.String;
|
|
68
|
+
readonly insertionIndex: Schema.Finite;
|
|
69
|
+
}>, Schema.TaggedStruct<"duplicateNode", {
|
|
70
|
+
readonly nodeId: Schema.String;
|
|
71
|
+
}>, Schema.TaggedStruct<"removeNode", {
|
|
72
|
+
readonly nodeId: Schema.String;
|
|
73
|
+
}>]>;
|
|
74
|
+
readonly diagnostics: Schema.$Array<Schema.Struct<{
|
|
75
|
+
readonly code: Schema.String;
|
|
76
|
+
readonly message: Schema.String;
|
|
77
|
+
readonly span: Schema.Struct<{
|
|
78
|
+
readonly start: Schema.Finite;
|
|
79
|
+
readonly end: Schema.Finite;
|
|
80
|
+
}>;
|
|
81
|
+
readonly repair: Schema.optional<Schema.Struct<{
|
|
82
|
+
readonly kind: Schema.Literals<readonly ["replace-class", "remove-class", "rewrite-node", "use-primitive"]>;
|
|
83
|
+
readonly raw: Schema.optional<Schema.String>;
|
|
84
|
+
readonly suggestions: Schema.$Array<Schema.String>;
|
|
85
|
+
readonly explanation: Schema.String;
|
|
86
|
+
}>>;
|
|
87
|
+
}>>;
|
|
88
|
+
}>;
|
|
89
|
+
interface SmlOpResult extends Schema.Schema.Type<typeof SmlOpResultSchema> {}
|
|
90
|
+
declare const ApplyOpsResultSchema: Schema.Struct<{
|
|
91
|
+
readonly source: Schema.String;
|
|
92
|
+
readonly revision: Schema.String;
|
|
93
|
+
readonly diagnostics: Schema.$Array<Schema.Struct<{
|
|
94
|
+
readonly code: Schema.String;
|
|
95
|
+
readonly message: Schema.String;
|
|
96
|
+
readonly span: Schema.Struct<{
|
|
97
|
+
readonly start: Schema.Finite;
|
|
98
|
+
readonly end: Schema.Finite;
|
|
99
|
+
}>;
|
|
100
|
+
readonly repair: Schema.optional<Schema.Struct<{
|
|
101
|
+
readonly kind: Schema.Literals<readonly ["replace-class", "remove-class", "rewrite-node", "use-primitive"]>;
|
|
102
|
+
readonly raw: Schema.optional<Schema.String>;
|
|
103
|
+
readonly suggestions: Schema.$Array<Schema.String>;
|
|
104
|
+
readonly explanation: Schema.String;
|
|
105
|
+
}>>;
|
|
106
|
+
}>>;
|
|
107
|
+
readonly results: Schema.$Array<Schema.Struct<{
|
|
108
|
+
readonly index: Schema.Finite;
|
|
109
|
+
readonly status: Schema.Literals<readonly ["applied", "failed"]>;
|
|
110
|
+
readonly op: Schema.Union<readonly [Schema.TaggedStruct<"setProp", {
|
|
111
|
+
readonly nodeId: Schema.String;
|
|
112
|
+
readonly name: Schema.String;
|
|
113
|
+
readonly value: Schema.NullOr<Schema.Union<readonly [Schema.Struct<{
|
|
114
|
+
readonly kind: Schema.Literal<"string">;
|
|
115
|
+
readonly value: Schema.String;
|
|
116
|
+
}>, Schema.Struct<{
|
|
117
|
+
readonly kind: Schema.Literal<"number">;
|
|
118
|
+
readonly value: Schema.Finite;
|
|
119
|
+
}>]>>;
|
|
120
|
+
}>, Schema.TaggedStruct<"setChildren", {
|
|
121
|
+
readonly nodeId: Schema.String;
|
|
122
|
+
readonly children: Schema.$Array<Schema.Codec<SmlNode, SmlNode, never, never>>;
|
|
123
|
+
}>, Schema.TaggedStruct<"insertBlock", {
|
|
124
|
+
readonly tag: Schema.Literals<readonly ["Email", "Subject", "Preview", "Container", "Section", "Row", "Column", "Heading", "Text", "Button", "Image", "Divider", "Spacer", "List", "ListItem", "If", "Else", "strong", "em", "a", "Source", "Sms", "WhatsApp", "Header", "Body", "Footer", "Buttons"]>;
|
|
125
|
+
readonly referenceId: Schema.NullOr<Schema.String>;
|
|
126
|
+
readonly position: Schema.Literals<readonly ["before", "after", "inside"]>;
|
|
127
|
+
}>, Schema.TaggedStruct<"insertSnippet", {
|
|
128
|
+
readonly snippet: Schema.String;
|
|
129
|
+
readonly referenceId: Schema.NullOr<Schema.String>;
|
|
130
|
+
readonly position: Schema.Literals<readonly ["before", "after", "inside"]>;
|
|
131
|
+
}>, Schema.TaggedStruct<"moveNode", {
|
|
132
|
+
readonly nodeId: Schema.String;
|
|
133
|
+
readonly targetParentId: Schema.String;
|
|
134
|
+
readonly insertionIndex: Schema.Finite;
|
|
135
|
+
}>, Schema.TaggedStruct<"duplicateNode", {
|
|
136
|
+
readonly nodeId: Schema.String;
|
|
137
|
+
}>, Schema.TaggedStruct<"removeNode", {
|
|
138
|
+
readonly nodeId: Schema.String;
|
|
139
|
+
}>]>;
|
|
140
|
+
readonly diagnostics: Schema.$Array<Schema.Struct<{
|
|
141
|
+
readonly code: Schema.String;
|
|
142
|
+
readonly message: Schema.String;
|
|
143
|
+
readonly span: Schema.Struct<{
|
|
144
|
+
readonly start: Schema.Finite;
|
|
145
|
+
readonly end: Schema.Finite;
|
|
146
|
+
}>;
|
|
147
|
+
readonly repair: Schema.optional<Schema.Struct<{
|
|
148
|
+
readonly kind: Schema.Literals<readonly ["replace-class", "remove-class", "rewrite-node", "use-primitive"]>;
|
|
149
|
+
readonly raw: Schema.optional<Schema.String>;
|
|
150
|
+
readonly suggestions: Schema.$Array<Schema.String>;
|
|
151
|
+
readonly explanation: Schema.String;
|
|
152
|
+
}>>;
|
|
153
|
+
}>>;
|
|
154
|
+
}>>;
|
|
155
|
+
}>;
|
|
156
|
+
interface ApplyOpsResult extends Schema.Schema.Type<typeof ApplyOpsResultSchema> {}
|
|
157
|
+
interface ApplyOpsOptions {
|
|
158
|
+
readonly expectedRevision?: string | number | undefined;
|
|
159
|
+
readonly currentRevision?: string | number | undefined;
|
|
160
|
+
}
|
|
161
|
+
declare const SmlOpError_base: Schema.Class<SmlOpError, Schema.TaggedStruct<"SmlOpError", {
|
|
162
|
+
readonly diagnostics: Schema.$Array<Schema.Struct<{
|
|
163
|
+
readonly code: Schema.String;
|
|
164
|
+
readonly message: Schema.String;
|
|
165
|
+
readonly span: Schema.Struct<{
|
|
166
|
+
readonly start: Schema.Finite;
|
|
167
|
+
readonly end: Schema.Finite;
|
|
168
|
+
}>;
|
|
169
|
+
readonly repair: Schema.optional<Schema.Struct<{
|
|
170
|
+
readonly kind: Schema.Literals<readonly ["replace-class", "remove-class", "rewrite-node", "use-primitive"]>;
|
|
171
|
+
readonly raw: Schema.optional<Schema.String>;
|
|
172
|
+
readonly suggestions: Schema.$Array<Schema.String>;
|
|
173
|
+
readonly explanation: Schema.String;
|
|
174
|
+
}>>;
|
|
175
|
+
}>>;
|
|
176
|
+
}>, import("effect/Cause").YieldableError>;
|
|
177
|
+
declare class SmlOpError extends SmlOpError_base {
|
|
178
|
+
get message(): string;
|
|
179
|
+
}
|
|
180
|
+
declare const sourceRevision: (source: string) => string;
|
|
181
|
+
declare const normalizeSml: (source: string) => Result.Result<string, SmlParseError>;
|
|
182
|
+
/**
|
|
183
|
+
* Apply a batch of ops to SML source, returning the rewritten source, its new
|
|
184
|
+
* revision, and a per-op result.
|
|
185
|
+
*
|
|
186
|
+
* Id contract: every id in the batch resolves against the id-space of the
|
|
187
|
+
* source the caller read (the `expectedRevision` snapshot). Ids are positional
|
|
188
|
+
* (`n0..nN` in document order) and are NOT rewritten between ops, so:
|
|
189
|
+
*
|
|
190
|
+
* - An op cannot target a node created earlier in the same batch — freshly
|
|
191
|
+
* inserted/duplicated nodes carry a blank id until the next reprint reassigns
|
|
192
|
+
* positional ids, and are unaddressable within the batch (fails with
|
|
193
|
+
* `op-target-not-found`).
|
|
194
|
+
* - After `duplicateNode`, the duplicated id still addresses the ORIGINAL (the
|
|
195
|
+
* first match in document order); the clone is a blank-id copy.
|
|
196
|
+
* - Structural ops (insert/remove/move) do not shift the ids of the nodes that
|
|
197
|
+
* survive, so a later op targeting a surviving sibling lands on the intended
|
|
198
|
+
* node regardless of what earlier ops did.
|
|
199
|
+
*
|
|
200
|
+
* Each op is still preflighted (reprint, reparse, compile, compatibility check)
|
|
201
|
+
* as an independent validity gate; a failing op is recorded as `failed` and
|
|
202
|
+
* does not advance the working document.
|
|
203
|
+
*/
|
|
204
|
+
declare const applyOps: (source: string, ops: readonly SmlOp[], options?: ApplyOpsOptions) => Result.Result<ApplyOpsResult, SmlOpError>;
|
|
205
|
+
declare const applyOp: (source: string, op: SmlOp, options?: ApplyOpsOptions) => Result.Result<ApplyOpsResult, SmlOpError>;
|
|
206
|
+
//#endregion
|
|
207
|
+
export { ApplyOpsOptions, ApplyOpsResult, ApplyOpsResultSchema, SmlOp, SmlOpError, SmlOpResult, SmlOpResultSchema, SmlOpSchema, applyOp, applyOps, normalizeSml, sourceRevision };
|
|
208
|
+
//# sourceMappingURL=ops.d.ts.map
|