svgbridge 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/README.md ADDED
@@ -0,0 +1,55 @@
1
+ <div align="center">
2
+
3
+ # svgbridge
4
+
5
+ ### Small adapters for rendering Artboards visual documents as SVG.
6
+
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![Module](https://img.shields.io/badge/module-ESM-f7df1e?logo=javascript&logoColor=111827)](package.json) [![Status](https://img.shields.io/badge/status-pre--alpha-f5a623)](https://artboards.dev)
8
+
9
+ [artboards.dev](https://artboards.dev)
10
+
11
+ </div>
12
+
13
+ `svgbridge` is a small, DOM-free SVG target for the portable visual document
14
+ primitives exported by `artboards`. The same document can be sent to another
15
+ renderer such as `canvasbridge`.
16
+
17
+ ## Install
18
+
19
+ ```sh
20
+ npm i artboards svgbridge
21
+ ```
22
+
23
+ ```ts
24
+ import { renderSvg } from "svgbridge";
25
+
26
+ const svg = renderSvg({
27
+ width: 320,
28
+ height: 180,
29
+ children: [
30
+ { type: "rect", x: 10, y: 10, width: 80, height: 40, fill: "#06c" },
31
+ ],
32
+ });
33
+ ```
34
+
35
+ ## Architecture
36
+
37
+ ```text
38
+ artboards.dev
39
+
40
+
41
+ artboards
42
+ portable visual model
43
+
44
+
45
+ svgbridge
46
+
47
+
48
+ SVG
49
+ ```
50
+
51
+ Supported basics are groups, rectangles, ellipses, lines, portable path
52
+ commands, text, image references, transforms, fill/stroke, opacity, and
53
+ document sizing. Output is deterministic and requires no browser DOM. Advanced
54
+ text shaping, gradients, clipping, masks, asset fetching, layout, and
55
+ application UI are out of scope until Artboards defines portable equivalents.
@@ -0,0 +1,14 @@
1
+ import type { PathCommand, Style, Transform, VisualDocument, VisualNode } from "artboards";
2
+ export type SvgNode = VisualNode;
3
+ export type SvgDocument = VisualDocument;
4
+ /** Converts the shared portable transform into deterministic SVG syntax. */
5
+ export declare function toSvgTransform(transform: Transform | undefined): string | undefined;
6
+ /** Serializes shared portable path commands as SVG path data. */
7
+ export declare function toSvgPath(commands?: readonly PathCommand[]): string;
8
+ /** Maps portable style properties to SVG attributes. */
9
+ export declare function toSvgPaint(style: Style): string;
10
+ /** Renders one shared visual node without requiring a browser DOM. */
11
+ export declare function renderSvgElement(node: SvgNode): string;
12
+ /** Produces stable, DOM-free SVG markup for one Artboards visual document. */
13
+ export declare function renderSvg(document: SvgDocument): string;
14
+ export declare const serializeSvg: typeof renderSvg;
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ function r(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function i(t,e){return e===void 0?"":` ${t}="${r(String(e))}"`}function p(t){if(!t)return;const e=[];return t.matrix&&e.push(`matrix(${t.matrix.join(" ")})`),t.translate&&e.push(`translate(${t.translate.x} ${t.translate.y})`),t.origin&&e.push(`translate(${t.origin.x} ${t.origin.y})`),t.rotate!==void 0&&e.push(`rotate(${t.rotate*180/Math.PI})`),t.scale&&e.push(`scale(${t.scale.x} ${t.scale.y})`),t.origin&&e.push(`translate(${-t.origin.x} ${-t.origin.y})`),e.length?e.join(" "):void 0}function s(t=[]){return t.map(e=>{switch(e.type){case"moveTo":return`M ${e.x} ${e.y}`;case"lineTo":return`L ${e.x} ${e.y}`;case"quadraticCurveTo":return`Q ${e.cpx} ${e.cpy} ${e.x} ${e.y}`;case"bezierCurveTo":return`C ${e.cp1x} ${e.cp1y} ${e.cp2x} ${e.cp2y} ${e.x} ${e.y}`;case"arc":{const h=Math.abs(e.endAngle-e.startAngle)%(Math.PI*2),u=e.x+e.radius*Math.cos(e.endAngle),g=e.y+e.radius*Math.sin(e.endAngle);return`A ${e.radius} ${e.radius} 0 ${h>Math.PI?1:0} ${e.counterclockwise?0:1} ${u} ${g}`}case"closePath":return"Z"}}).join(" ")}function x(t){return[i("fill",t.fill),i("stroke",t.stroke),i("stroke-width",t.strokeWidth),i("opacity",t.opacity)].join("")}function l(t){return[i("x",t.x),i("y",t.y),i("width",t.width),i("height",t.height),i("cx",t.cx),i("cy",t.cy),i("rx",t.rx),i("ry",t.ry),i("x1",t.x1),i("y1",t.y1),i("x2",t.x2),i("y2",t.y2),i("href",t.href),i("transform",p(t.transform)),x(t)].join("")}function $(t){const e=l(t);return t.type==="group"?`<g${e}>${(t.children??[]).map($).join("")}</g>`:t.type==="path"?`<path${e}${i("d",s(t.path))}/>`:t.type==="text"?`<text${e}>${r(t.text??"")}</text>`:`<${t.type}${e}/>`}function a(t){const e=t.background===void 0?"":`<rect width="${t.width}" height="${t.height}" fill="${r(t.background)}"/>`;return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${t.width} ${t.height}" width="${t.width}" height="${t.height}">${e}${(t.children??[]).map($).join("")}</svg>`}const n=a;export{a as renderSvg,$ as renderSvgElement,n as serializeSvg,x as toSvgPaint,s as toSvgPath,p as toSvgTransform};
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "svgbridge",
3
+ "version": "0.1.0",
4
+ "description": "Small adapters for rendering Artboards visual documents as SVG.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "default": "./dist/index.js" } },
9
+ "files": ["dist", "README.md"],
10
+ "sideEffects": false,
11
+ "scripts": { "build": "tsc --project tsconfig.json", "postbuild": "npm run dist --prefix \"$npm_config_local_prefix\" -- \"$PWD\"", "prepack": "npm run build", "pretest": "npm run build", "test": "node --test test/*.test.mjs" },
12
+ "keywords": ["artboards", "svg", "renderer"],
13
+ "homepage": "https://artboards.dev",
14
+ "license": "MIT",
15
+ "engines": { "node": ">=20" },
16
+ "publishConfig": { "access": "public" },
17
+ "dependencies": { "artboards": "^0.0.1" },
18
+ "devDependencies": { "typescript": "^5.9.3" }
19
+ }