@webstudio-is/css-engine 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Webstudio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,4 @@
1
+ ## CSS Engine
2
+
3
+ This package is designed to render effectively CSS in the format produced by Webstudio Designer.
4
+ It is using CSS variables for all dynamic parts and can render at runtime as for usage on Live Canvas in the Designer as well as for extracting a fully static style sheet for production.
@@ -0,0 +1,3 @@
1
+ import { CssEngine } from "./css-engine";
2
+ export declare const createCssEngine: () => CssEngine;
3
+ //# sourceMappingURL=create-css-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-css-engine.d.ts","sourceRoot":"","sources":["../../src/core/create-css-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,iBAE3B,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCssEngine = void 0;
4
+ const css_engine_1 = require("./css-engine");
5
+ const createCssEngine = () => {
6
+ return new css_engine_1.CssEngine();
7
+ };
8
+ exports.createCssEngine = createCssEngine;
@@ -0,0 +1,14 @@
1
+ import type { CssRule } from "@webstudio-is/css-data";
2
+ import { MediaRule, PlaintextRule, StyleRule, type FontFaceOptions, type MediaRuleOptions } from "./rules";
3
+ export declare class CssEngine {
4
+ #private;
5
+ constructor();
6
+ addMediaRule(id: string, options?: MediaRuleOptions): MediaRule;
7
+ addStyleRule(selectorText: string, rule: CssRule): StyleRule | PlaintextRule;
8
+ addPlaintextRule(cssText: string): PlaintextRule | Map<string, PlaintextRule>;
9
+ addFontFaceRule(options: FontFaceOptions): number;
10
+ clear(): void;
11
+ render(): void;
12
+ get cssText(): string;
13
+ }
14
+ //# sourceMappingURL=css-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-engine.d.ts","sourceRoot":"","sources":["../../src/core/css-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAEL,SAAS,EACT,aAAa,EACb,SAAS,EACT,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAC;AAMjB,qBAAa,SAAS;;;IAapB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB;IASnD,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;IAahD,gBAAgB,CAAC,OAAO,EAAE,MAAM;IAKhC,eAAe,CAAC,OAAO,EAAE,eAAe;IAGxC,KAAK;IAML,MAAM;IAKN,IAAI,OAAO,WAiBV;CAKF"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _CssEngine_element, _CssEngine_mediaRules, _CssEngine_plainRules, _CssEngine_fontFaceRules, _CssEngine_sheet, _CssEngine_isDirty, _CssEngine_cssText, _CssEngine_onChangeRule;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CssEngine = void 0;
16
+ const rules_1 = require("./rules");
17
+ const style_element_1 = require("./style-element");
18
+ const style_sheet_1 = require("./style-sheet");
19
+ const defaultMediaRuleId = "__default-media-rule__";
20
+ class CssEngine {
21
+ constructor() {
22
+ _CssEngine_element.set(this, void 0);
23
+ _CssEngine_mediaRules.set(this, new Map());
24
+ _CssEngine_plainRules.set(this, new Map());
25
+ _CssEngine_fontFaceRules.set(this, []);
26
+ _CssEngine_sheet.set(this, void 0);
27
+ _CssEngine_isDirty.set(this, false);
28
+ _CssEngine_cssText.set(this, "");
29
+ _CssEngine_onChangeRule.set(this, () => {
30
+ __classPrivateFieldSet(this, _CssEngine_isDirty, true, "f");
31
+ });
32
+ __classPrivateFieldSet(this, _CssEngine_element, new style_element_1.StyleElement(), "f");
33
+ __classPrivateFieldSet(this, _CssEngine_sheet, new style_sheet_1.StyleSheet(__classPrivateFieldGet(this, _CssEngine_element, "f")), "f");
34
+ this.addMediaRule(defaultMediaRuleId);
35
+ }
36
+ addMediaRule(id, options) {
37
+ let mediaRule = __classPrivateFieldGet(this, _CssEngine_mediaRules, "f").get(id);
38
+ if (mediaRule === undefined) {
39
+ mediaRule = new rules_1.MediaRule(options);
40
+ __classPrivateFieldGet(this, _CssEngine_mediaRules, "f").set(id, mediaRule);
41
+ __classPrivateFieldSet(this, _CssEngine_isDirty, true, "f");
42
+ }
43
+ return mediaRule;
44
+ }
45
+ addStyleRule(selectorText, rule) {
46
+ const mediaRule = __classPrivateFieldGet(this, _CssEngine_mediaRules, "f").get(rule.breakpoint) ??
47
+ __classPrivateFieldGet(this, _CssEngine_mediaRules, "f").get(defaultMediaRuleId);
48
+ __classPrivateFieldSet(this, _CssEngine_isDirty, true, "f");
49
+ const styleRule = new rules_1.StyleRule(selectorText, rule.style);
50
+ styleRule.onChange = __classPrivateFieldGet(this, _CssEngine_onChangeRule, "f");
51
+ if (mediaRule === undefined) {
52
+ // Should be impossible to reach.
53
+ throw new Error("No media rule found");
54
+ }
55
+ return mediaRule.insertRule(styleRule);
56
+ }
57
+ addPlaintextRule(cssText) {
58
+ const rule = __classPrivateFieldGet(this, _CssEngine_plainRules, "f").get(cssText);
59
+ if (rule !== undefined)
60
+ return rule;
61
+ return __classPrivateFieldGet(this, _CssEngine_plainRules, "f").set(cssText, new rules_1.PlaintextRule(cssText));
62
+ }
63
+ addFontFaceRule(options) {
64
+ return __classPrivateFieldGet(this, _CssEngine_fontFaceRules, "f").push(new rules_1.FontFaceRule(options));
65
+ }
66
+ clear() {
67
+ __classPrivateFieldGet(this, _CssEngine_mediaRules, "f").clear();
68
+ __classPrivateFieldGet(this, _CssEngine_plainRules, "f").clear();
69
+ __classPrivateFieldSet(this, _CssEngine_fontFaceRules, [], "f");
70
+ __classPrivateFieldSet(this, _CssEngine_isDirty, true, "f");
71
+ }
72
+ render() {
73
+ __classPrivateFieldGet(this, _CssEngine_element, "f").mount();
74
+ // This isn't going to do anything if the `cssText` hasn't changed.
75
+ __classPrivateFieldGet(this, _CssEngine_sheet, "f").replaceSync(this.cssText);
76
+ }
77
+ get cssText() {
78
+ if (__classPrivateFieldGet(this, _CssEngine_isDirty, "f") === false) {
79
+ return __classPrivateFieldGet(this, _CssEngine_cssText, "f");
80
+ }
81
+ __classPrivateFieldSet(this, _CssEngine_isDirty, false, "f");
82
+ const css = [];
83
+ css.push(...__classPrivateFieldGet(this, _CssEngine_fontFaceRules, "f").map((rule) => rule.cssText));
84
+ for (const plaintextRule of __classPrivateFieldGet(this, _CssEngine_plainRules, "f").values()) {
85
+ css.push(plaintextRule.cssText);
86
+ }
87
+ for (const mediaRule of __classPrivateFieldGet(this, _CssEngine_mediaRules, "f").values()) {
88
+ const { cssText } = mediaRule;
89
+ if (cssText !== "")
90
+ css.push(cssText);
91
+ }
92
+ __classPrivateFieldSet(this, _CssEngine_cssText, css.join("\n"), "f");
93
+ return __classPrivateFieldGet(this, _CssEngine_cssText, "f");
94
+ }
95
+ }
96
+ exports.CssEngine = CssEngine;
97
+ _CssEngine_element = new WeakMap(), _CssEngine_mediaRules = new WeakMap(), _CssEngine_plainRules = new WeakMap(), _CssEngine_fontFaceRules = new WeakMap(), _CssEngine_sheet = new WeakMap(), _CssEngine_isDirty = new WeakMap(), _CssEngine_cssText = new WeakMap(), _CssEngine_onChangeRule = new WeakMap();
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ component: string;
3
+ };
4
+ export default _default;
5
+ export declare const Basic: () => JSX.Element;
6
+ //# sourceMappingURL=css-engine.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-engine.stories.d.ts","sourceRoot":"","sources":["../../src/core/css-engine.stories.tsx"],"names":[],"mappings":";;;AAEA,wBAEE;AASF,eAAO,MAAM,KAAK,mBAkCjB,CAAC"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Basic = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const css_engine_1 = require("./css-engine");
6
+ exports.default = {
7
+ component: "CssEngine",
8
+ };
9
+ const style0 = {
10
+ color: { type: "keyword", value: "red" },
11
+ };
12
+ const mediaRuleOptions0 = { minWidth: 0 };
13
+ const mediaId = "0";
14
+ const Basic = () => {
15
+ const engine = new css_engine_1.CssEngine();
16
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
17
+ const rule = engine.addStyleRule(".test", {
18
+ style: style0,
19
+ breakpoint: "0",
20
+ });
21
+ engine.render();
22
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "test", children: "Should be red" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
23
+ rule.styleMap.set("color", { type: "keyword", value: "green" });
24
+ engine.render();
25
+ }, children: "Make it green" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
26
+ engine.addStyleRule(".test", {
27
+ style: {
28
+ background: { type: "keyword", value: "yellow" },
29
+ },
30
+ breakpoint: "0",
31
+ });
32
+ engine.render();
33
+ }, children: "Add rule with yellow background" })] }));
34
+ };
35
+ exports.Basic = Basic;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=css-engine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-engine.test.d.ts","sourceRoot":"","sources":["../../src/core/css-engine.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const css_engine_1 = require("./css-engine");
4
+ const style0 = {
5
+ display: { type: "keyword", value: "block" },
6
+ };
7
+ const mediaRuleOptions0 = { minWidth: 0 };
8
+ const mediaId = "0";
9
+ describe("CssEngine", () => {
10
+ let engine;
11
+ beforeEach(() => {
12
+ engine = new css_engine_1.CssEngine();
13
+ });
14
+ test("use default media rule when there is no matching one registrered", () => {
15
+ engine.addStyleRule(".c", {
16
+ style: style0,
17
+ breakpoint: "0",
18
+ });
19
+ expect(engine.cssText).toMatchInlineSnapshot(`
20
+ "@media all {
21
+ .c { display: block }
22
+ }"
23
+ `);
24
+ engine.addStyleRule(".c1", {
25
+ style: { color: { type: "keyword", value: "red" } },
26
+ breakpoint: "0",
27
+ });
28
+ expect(engine.cssText).toMatchInlineSnapshot(`
29
+ "@media all {
30
+ .c { display: block }
31
+ .c1 { color: red }
32
+ }"
33
+ `);
34
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
35
+ engine.addStyleRule(".c1", {
36
+ style: { color: { type: "keyword", value: "blue" } },
37
+ breakpoint: "0",
38
+ });
39
+ // Default media query should allways be the first to have the lowest source order specificity
40
+ expect(engine.cssText).toMatchInlineSnapshot(`
41
+ "@media all {
42
+ .c { display: block }
43
+ .c1 { color: red }
44
+ }
45
+ @media all and (min-width: 0px) {
46
+ .c1 { color: blue }
47
+ }"
48
+ `);
49
+ });
50
+ test("rule with multiple properties", () => {
51
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
52
+ engine.addStyleRule(".c", {
53
+ style: {
54
+ ...style0,
55
+ color: { type: "keyword", value: "red" },
56
+ },
57
+ breakpoint: "0",
58
+ });
59
+ expect(engine.cssText).toMatchInlineSnapshot(`
60
+ "@media all and (min-width: 0px) {
61
+ .c { display: block; color: red }
62
+ }"
63
+ `);
64
+ });
65
+ test("hyphenate property", () => {
66
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
67
+ engine.addStyleRule(".c", {
68
+ style: {
69
+ backgroundColor: { type: "keyword", value: "red" },
70
+ },
71
+ breakpoint: "0",
72
+ });
73
+ expect(engine.cssText).toMatchInlineSnapshot(`
74
+ "@media all and (min-width: 0px) {
75
+ .c { background-color: red }
76
+ }"
77
+ `);
78
+ });
79
+ test("add rule", () => {
80
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
81
+ const rule1 = engine.addStyleRule(".c", {
82
+ style: {
83
+ ...style0,
84
+ color: { type: "keyword", value: "red" },
85
+ },
86
+ breakpoint: "0",
87
+ });
88
+ expect(engine.cssText).toMatchInlineSnapshot(`
89
+ "@media all and (min-width: 0px) {
90
+ .c { display: block; color: red }
91
+ }"
92
+ `);
93
+ expect(rule1.cssText).toMatchInlineSnapshot(`".c { display: block; color: red }"`);
94
+ engine.addStyleRule(".c2", {
95
+ style: {
96
+ ...style0,
97
+ color: { type: "keyword", value: "green" },
98
+ },
99
+ breakpoint: "0",
100
+ });
101
+ expect(engine.cssText).toMatchInlineSnapshot(`
102
+ "@media all and (min-width: 0px) {
103
+ .c { display: block; color: red }
104
+ .c2 { display: block; color: green }
105
+ }"
106
+ `);
107
+ });
108
+ test("update rule", () => {
109
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
110
+ const rule = engine.addStyleRule(".c", {
111
+ style: {
112
+ ...style0,
113
+ color: { type: "keyword", value: "red" },
114
+ },
115
+ breakpoint: "0",
116
+ });
117
+ expect(engine.cssText).toMatchInlineSnapshot(`
118
+ "@media all and (min-width: 0px) {
119
+ .c { display: block; color: red }
120
+ }"
121
+ `);
122
+ expect(rule.cssText).toMatchInlineSnapshot(`".c { display: block; color: red }"`);
123
+ rule.styleMap.set("color", { type: "keyword", value: "green" });
124
+ expect(rule.cssText).toMatchInlineSnapshot(`".c { display: block; color: green }"`);
125
+ expect(engine.cssText).toMatchInlineSnapshot(`
126
+ "@media all and (min-width: 0px) {
127
+ .c { display: block; color: green }
128
+ }"
129
+ `);
130
+ });
131
+ test("don't override media queries", () => {
132
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
133
+ engine.addStyleRule(".c", {
134
+ style: style0,
135
+ breakpoint: "0",
136
+ });
137
+ expect(engine.cssText).toMatchInlineSnapshot(`
138
+ "@media all and (min-width: 0px) {
139
+ .c { display: block }
140
+ }"
141
+ `);
142
+ engine.addMediaRule(mediaId, mediaRuleOptions0);
143
+ expect(engine.cssText).toMatchInlineSnapshot(`
144
+ "@media all and (min-width: 0px) {
145
+ .c { display: block }
146
+ }"
147
+ `);
148
+ });
149
+ test("plaintext rule", () => {
150
+ engine.addPlaintextRule(".c { color: red }");
151
+ expect(engine.cssText).toMatchInlineSnapshot(`".c { color: red }"`);
152
+ });
153
+ test("plaintext - no duplicates", () => {
154
+ engine.addPlaintextRule(".c { color: red }");
155
+ engine.addPlaintextRule(".c { color: red }");
156
+ engine.addPlaintextRule(".c { color: green }");
157
+ expect(engine.cssText).toMatchInlineSnapshot(`
158
+ ".c { color: red }
159
+ .c { color: green }"
160
+ `);
161
+ });
162
+ test("font family rule", () => {
163
+ engine.addFontFaceRule({
164
+ fontFamily: "Roboto",
165
+ fontStyle: "normal",
166
+ fontWeight: 400,
167
+ fontDisplay: "swap",
168
+ src: "url(/src)",
169
+ });
170
+ expect(engine.cssText).toMatchInlineSnapshot(`
171
+ "@font-face {
172
+ font-family: Roboto; font-style: normal; font-weight: 400; font-display: swap; src: url(/src);
173
+ }"
174
+ `);
175
+ });
176
+ test("clear", () => {
177
+ engine.addStyleRule(".c", {
178
+ style: style0,
179
+ breakpoint: "0",
180
+ });
181
+ engine.clear();
182
+ expect(engine.cssText).toMatchInlineSnapshot(`""`);
183
+ });
184
+ });
@@ -0,0 +1,5 @@
1
+ export { CssEngine } from "./css-engine";
2
+ export type { AnyRule, StyleRule, MediaRule, PlaintextRule, FontFaceRule, } from "./rules";
3
+ export * from "./create-css-engine";
4
+ export * from "./to-value";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,aAAa,EACb,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.CssEngine = void 0;
18
+ var css_engine_1 = require("./css-engine");
19
+ Object.defineProperty(exports, "CssEngine", { enumerable: true, get: function () { return css_engine_1.CssEngine; } });
20
+ __exportStar(require("./create-css-engine"), exports);
21
+ __exportStar(require("./to-value"), exports);
@@ -0,0 +1,47 @@
1
+ import type { Style, StyleProperty, StyleValue } from "@webstudio-is/css-data";
2
+ declare class StylePropertyMap {
3
+ #private;
4
+ onChange?: () => void;
5
+ set(property: StyleProperty, value?: StyleValue): void;
6
+ toString(): string;
7
+ }
8
+ export declare class StyleRule {
9
+ #private;
10
+ styleMap: StylePropertyMap;
11
+ selectorText: string;
12
+ onChange?: () => void;
13
+ constructor(selectorText: string, style: Style);
14
+ get cssText(): string;
15
+ }
16
+ export declare type MediaRuleOptions = {
17
+ minWidth?: number;
18
+ maxWidth?: number;
19
+ mediaType?: "all" | "screen" | "print";
20
+ };
21
+ export declare class MediaRule {
22
+ #private;
23
+ rules: Array<StyleRule | PlaintextRule>;
24
+ constructor(options?: MediaRuleOptions);
25
+ insertRule(rule: StyleRule | PlaintextRule): StyleRule | PlaintextRule;
26
+ get cssText(): string;
27
+ }
28
+ export declare class PlaintextRule {
29
+ cssText: string;
30
+ styleMap: Map<any, any>;
31
+ constructor(cssText: string);
32
+ }
33
+ export declare type FontFaceOptions = {
34
+ fontFamily: string;
35
+ fontStyle: "normal" | "italic" | "oblique";
36
+ fontWeight: number;
37
+ fontDisplay: "swap" | "auto" | "block" | "fallback" | "optional";
38
+ src: string;
39
+ };
40
+ export declare class FontFaceRule {
41
+ #private;
42
+ constructor(options: FontFaceOptions);
43
+ get cssText(): string;
44
+ }
45
+ export declare type AnyRule = StyleRule | MediaRule | PlaintextRule | FontFaceRule;
46
+ export {};
47
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/core/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAI/E,cAAM,gBAAgB;;IAIpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,UAAU;IAK/C,QAAQ;CAaT;AAED,qBAAa,SAAS;;IACpB,QAAQ,mBAAC;IACT,YAAY,SAAC;IACb,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;gBACV,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAY9C,IAAI,OAAO,WAEV;CACF;AAED,oBAAY,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;CACxC,CAAC;AAEF,qBAAa,SAAS;;IAEpB,KAAK,EAAE,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC,CAAM;gBAEjC,OAAO,GAAE,gBAAqB;IAI1C,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,aAAa;IAI1C,IAAI,OAAO,WAcV;CACF;AAED,qBAAa,aAAa;IACxB,OAAO,SAAC;IACR,QAAQ,gBAAa;gBACT,OAAO,EAAE,MAAM;CAG5B;AAED,oBAAY,eAAe,GAAG;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IACjE,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,qBAAa,YAAY;;gBAEX,OAAO,EAAE,eAAe;IAGpC,IAAI,OAAO,WAIV;CACF;AAED,oBAAY,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,YAAY,CAAC"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ var _StylePropertyMap_styleMap, _StylePropertyMap_isDirty, _StylePropertyMap_string, _StyleRule_onChange, _MediaRule_options, _MediaRule_mediaType, _FontFaceRule_options;
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.FontFaceRule = exports.PlaintextRule = exports.MediaRule = exports.StyleRule = void 0;
19
+ const hyphenate_style_name_1 = __importDefault(require("hyphenate-style-name"));
20
+ const to_value_1 = require("./to-value");
21
+ class StylePropertyMap {
22
+ constructor() {
23
+ _StylePropertyMap_styleMap.set(this, new Map());
24
+ _StylePropertyMap_isDirty.set(this, false);
25
+ _StylePropertyMap_string.set(this, "");
26
+ }
27
+ set(property, value) {
28
+ __classPrivateFieldGet(this, _StylePropertyMap_styleMap, "f").set(property, value);
29
+ __classPrivateFieldSet(this, _StylePropertyMap_isDirty, true, "f");
30
+ this.onChange?.();
31
+ }
32
+ toString() {
33
+ if (__classPrivateFieldGet(this, _StylePropertyMap_isDirty, "f") === false) {
34
+ return __classPrivateFieldGet(this, _StylePropertyMap_string, "f");
35
+ }
36
+ const block = [];
37
+ for (const [property, value] of __classPrivateFieldGet(this, _StylePropertyMap_styleMap, "f")) {
38
+ if (value === undefined)
39
+ continue;
40
+ block.push(`${(0, hyphenate_style_name_1.default)(property)}: ${(0, to_value_1.toValue)(value)}`);
41
+ }
42
+ __classPrivateFieldSet(this, _StylePropertyMap_string, block.join("; "), "f");
43
+ __classPrivateFieldSet(this, _StylePropertyMap_isDirty, false, "f");
44
+ return __classPrivateFieldGet(this, _StylePropertyMap_string, "f");
45
+ }
46
+ }
47
+ _StylePropertyMap_styleMap = new WeakMap(), _StylePropertyMap_isDirty = new WeakMap(), _StylePropertyMap_string = new WeakMap();
48
+ class StyleRule {
49
+ constructor(selectorText, style) {
50
+ _StyleRule_onChange.set(this, () => {
51
+ this.onChange?.();
52
+ });
53
+ this.styleMap = new StylePropertyMap();
54
+ this.selectorText = selectorText;
55
+ let property;
56
+ for (property in style) {
57
+ this.styleMap.set(property, style[property]);
58
+ }
59
+ this.styleMap.onChange = __classPrivateFieldGet(this, _StyleRule_onChange, "f");
60
+ }
61
+ get cssText() {
62
+ return `${this.selectorText} { ${this.styleMap} }`;
63
+ }
64
+ }
65
+ exports.StyleRule = StyleRule;
66
+ _StyleRule_onChange = new WeakMap();
67
+ class MediaRule {
68
+ constructor(options = {}) {
69
+ _MediaRule_options.set(this, void 0);
70
+ this.rules = [];
71
+ _MediaRule_mediaType.set(this, void 0);
72
+ __classPrivateFieldSet(this, _MediaRule_options, options, "f");
73
+ __classPrivateFieldSet(this, _MediaRule_mediaType, options.mediaType ?? "all", "f");
74
+ }
75
+ insertRule(rule) {
76
+ this.rules.push(rule);
77
+ return rule;
78
+ }
79
+ get cssText() {
80
+ if (this.rules.length === 0)
81
+ return "";
82
+ const rules = [];
83
+ for (const rule of this.rules) {
84
+ rules.push(` ${rule.cssText}`);
85
+ }
86
+ let conditionText = "";
87
+ const { minWidth, maxWidth } = __classPrivateFieldGet(this, _MediaRule_options, "f");
88
+ if (minWidth !== undefined)
89
+ conditionText = `min-width: ${minWidth}px`;
90
+ if (maxWidth !== undefined)
91
+ conditionText = `max-width: ${maxWidth}px`;
92
+ if (conditionText)
93
+ conditionText = `and (${conditionText}) `;
94
+ return `@media ${__classPrivateFieldGet(this, _MediaRule_mediaType, "f")} ${conditionText}{\n${rules.join("\n")}\n}`;
95
+ }
96
+ }
97
+ exports.MediaRule = MediaRule;
98
+ _MediaRule_options = new WeakMap(), _MediaRule_mediaType = new WeakMap();
99
+ class PlaintextRule {
100
+ constructor(cssText) {
101
+ this.styleMap = new Map();
102
+ this.cssText = cssText;
103
+ }
104
+ }
105
+ exports.PlaintextRule = PlaintextRule;
106
+ class FontFaceRule {
107
+ constructor(options) {
108
+ _FontFaceRule_options.set(this, void 0);
109
+ __classPrivateFieldSet(this, _FontFaceRule_options, options, "f");
110
+ }
111
+ get cssText() {
112
+ const { fontFamily, fontStyle, fontWeight, fontDisplay, src } = __classPrivateFieldGet(this, _FontFaceRule_options, "f");
113
+ return `@font-face {\n font-family: ${fontFamily}; font-style: ${fontStyle}; font-weight: ${fontWeight}; font-display: ${fontDisplay}; src: ${src};\n}`;
114
+ }
115
+ }
116
+ exports.FontFaceRule = FontFaceRule;
117
+ _FontFaceRule_options = new WeakMap();
@@ -0,0 +1,8 @@
1
+ export declare class StyleElement {
2
+ #private;
3
+ get isMounted(): boolean;
4
+ mount(): void;
5
+ unmount(): void;
6
+ render(cssText: string): void;
7
+ }
8
+ //# sourceMappingURL=style-element.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-element.d.ts","sourceRoot":"","sources":["../../src/core/style-element.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;;IAEvB,IAAI,SAAS,YAEZ;IACD,KAAK;IAOL,OAAO;IAMP,MAAM,CAAC,OAAO,EAAE,MAAM;CAKvB"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
+ };
13
+ var _StyleElement_element;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.StyleElement = void 0;
16
+ class StyleElement {
17
+ constructor() {
18
+ _StyleElement_element.set(this, void 0);
19
+ }
20
+ get isMounted() {
21
+ return __classPrivateFieldGet(this, _StyleElement_element, "f")?.parentElement != null;
22
+ }
23
+ mount() {
24
+ if (this.isMounted === false) {
25
+ __classPrivateFieldSet(this, _StyleElement_element, document.createElement("style"), "f");
26
+ __classPrivateFieldGet(this, _StyleElement_element, "f").setAttribute("data-webstudio", "");
27
+ document.head.appendChild(__classPrivateFieldGet(this, _StyleElement_element, "f"));
28
+ }
29
+ }
30
+ unmount() {
31
+ if (this.isMounted) {
32
+ __classPrivateFieldGet(this, _StyleElement_element, "f")?.parentElement?.removeChild(__classPrivateFieldGet(this, _StyleElement_element, "f"));
33
+ __classPrivateFieldSet(this, _StyleElement_element, undefined, "f");
34
+ }
35
+ }
36
+ render(cssText) {
37
+ if (__classPrivateFieldGet(this, _StyleElement_element, "f")) {
38
+ __classPrivateFieldGet(this, _StyleElement_element, "f").textContent = cssText;
39
+ }
40
+ }
41
+ }
42
+ exports.StyleElement = StyleElement;
43
+ _StyleElement_element = new WeakMap();
@@ -0,0 +1,7 @@
1
+ import { StyleElement } from "./style-element";
2
+ export declare class StyleSheet {
3
+ #private;
4
+ constructor(element: StyleElement);
5
+ replaceSync(cssText: string): void;
6
+ }
7
+ //# sourceMappingURL=style-sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-sheet.d.ts","sourceRoot":"","sources":["../../src/core/style-sheet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,qBAAa,UAAU;;gBAGT,OAAO,EAAE,YAAY;IAGjC,WAAW,CAAC,OAAO,EAAE,MAAM;CAM5B"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _StyleSheet_cssText, _StyleSheet_element;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.StyleSheet = void 0;
16
+ class StyleSheet {
17
+ constructor(element) {
18
+ _StyleSheet_cssText.set(this, "");
19
+ _StyleSheet_element.set(this, void 0);
20
+ __classPrivateFieldSet(this, _StyleSheet_element, element, "f");
21
+ }
22
+ replaceSync(cssText) {
23
+ if (cssText !== __classPrivateFieldGet(this, _StyleSheet_cssText, "f")) {
24
+ __classPrivateFieldSet(this, _StyleSheet_cssText, cssText, "f");
25
+ __classPrivateFieldGet(this, _StyleSheet_element, "f").render(cssText);
26
+ }
27
+ }
28
+ }
29
+ exports.StyleSheet = StyleSheet;
30
+ _StyleSheet_cssText = new WeakMap(), _StyleSheet_element = new WeakMap();
@@ -0,0 +1,7 @@
1
+ import type { StyleValue } from "@webstudio-is/css-data";
2
+ declare type ToCssOptions = {
3
+ withFallback: boolean;
4
+ };
5
+ export declare const toValue: (value?: StyleValue, options?: ToCssOptions) => string;
6
+ export {};
7
+ //# sourceMappingURL=to-value.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-value.d.ts","sourceRoot":"","sources":["../../src/core/to-value.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,aAAK,YAAY,GAAG;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAMF,eAAO,MAAM,OAAO,WACV,UAAU,YACT,YAAY,KACpB,MA0BF,CAAC"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toValue = void 0;
4
+ const fonts_1 = require("@webstudio-is/fonts");
5
+ const defaultOptions = {
6
+ withFallback: true,
7
+ };
8
+ const toValue = (value, options = defaultOptions) => {
9
+ if (value === undefined)
10
+ return "";
11
+ if (value.type === "unit") {
12
+ return value.value + (value.unit === "number" ? "" : value.unit);
13
+ }
14
+ if (value.type === "fontFamily") {
15
+ if (options.withFallback === false) {
16
+ return value.value[0];
17
+ }
18
+ const family = value.value[0];
19
+ const fallbacks = fonts_1.SYSTEM_FONTS.get(family);
20
+ if (Array.isArray(fallbacks)) {
21
+ return [...value.value, ...fallbacks].join(", ");
22
+ }
23
+ return [...value.value, fonts_1.DEFAULT_FONT_FALLBACK].join(", ");
24
+ }
25
+ if (value.type === "var") {
26
+ const fallbacks = [];
27
+ for (const fallback of value.fallbacks) {
28
+ fallbacks.push((0, exports.toValue)(fallback, options));
29
+ }
30
+ const fallbacksString = fallbacks.length > 0 ? `, ${fallbacks.join(", ")}` : "";
31
+ return `var(--${value.value}${fallbacksString})`;
32
+ }
33
+ return value.value;
34
+ };
35
+ exports.toValue = toValue;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=to-value.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-value.test.d.ts","sourceRoot":"","sources":["../../src/core/to-value.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const to_value_1 = require("./to-value");
4
+ describe("Convert WS CSS Values to native CSS strings", () => {
5
+ test("keyword", () => {
6
+ const value = (0, to_value_1.toValue)({ type: "keyword", value: "red" });
7
+ expect(value).toBe("red");
8
+ });
9
+ test("unit", () => {
10
+ const value = (0, to_value_1.toValue)({ type: "unit", value: 10, unit: "px" });
11
+ expect(value).toBe("10px");
12
+ });
13
+ test("invalid", () => {
14
+ const value = (0, to_value_1.toValue)({ type: "invalid", value: "bad" });
15
+ expect(value).toBe("bad");
16
+ });
17
+ test("unset", () => {
18
+ const value = (0, to_value_1.toValue)({ type: "unset", value: "" });
19
+ expect(value).toBe("");
20
+ });
21
+ test("var", () => {
22
+ const value = (0, to_value_1.toValue)({ type: "var", value: "namespace", fallbacks: [] });
23
+ expect(value).toBe("var(--namespace)");
24
+ });
25
+ test("var with fallbacks", () => {
26
+ const value = (0, to_value_1.toValue)({
27
+ type: "var",
28
+ value: "namespace",
29
+ fallbacks: [
30
+ {
31
+ type: "keyword",
32
+ value: "normal",
33
+ },
34
+ {
35
+ type: "unit",
36
+ value: 10,
37
+ unit: "px",
38
+ },
39
+ ],
40
+ });
41
+ expect(value).toBe("var(--namespace, normal, 10px)");
42
+ });
43
+ test("fontFamily", () => {
44
+ const value = (0, to_value_1.toValue)({
45
+ type: "fontFamily",
46
+ value: ["Courier New"],
47
+ });
48
+ expect(value).toBe("Courier New, monospace");
49
+ });
50
+ test("withFallback=false", () => {
51
+ const value = (0, to_value_1.toValue)({
52
+ type: "fontFamily",
53
+ value: ["Courier New"],
54
+ }, { withFallback: false });
55
+ expect(value).toBe("Courier New");
56
+ });
57
+ });
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./core";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./core"), exports);
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@webstudio-is/css-engine",
3
+ "version": "0.1.0",
4
+ "description": "CSS Renderer for Webstudio",
5
+ "author": "Webstudio <github@webstudio.is>",
6
+ "homepage": "https://webstudio.is",
7
+ "scripts": {
8
+ "typecheck": "tsc --noEmit",
9
+ "checks": "yarn typecheck && yarn lint && yarn test",
10
+ "dev": "tsup --watch",
11
+ "build": "rm -fr lib tsconfig.tsbuildinfo && tsc",
12
+ "test": "jest",
13
+ "lint": "eslint ./src --ext .ts,.tsx --max-warnings 0",
14
+ "storybook:run": "start-storybook -p 6006",
15
+ "storybook:build": "build-storybook"
16
+ },
17
+ "dependencies": {
18
+ "hyphenate-style-name": "^1.0.4",
19
+ "react": "^17.0.2",
20
+ "react-dom": "^17.0.2",
21
+ "@webstudio-is/fonts": "*"
22
+ },
23
+ "devDependencies": {
24
+ "@storybook/addon-actions": "^6.5.6",
25
+ "@storybook/addon-essentials": "^6.5.6",
26
+ "@storybook/addon-interactions": "^6.5.12",
27
+ "@storybook/addon-links": "^6.5.6",
28
+ "@storybook/builder-webpack4": "^6.5.6",
29
+ "@storybook/jest": "^0.0.10",
30
+ "@storybook/manager-webpack4": "^6.5.6",
31
+ "@storybook/react": "^6.5.6",
32
+ "@storybook/testing-library": "^0.0.13",
33
+ "@webstudio-is/jest-config": "*",
34
+ "@webstudio-is/css-data": "*",
35
+ "tsup": "^6.1.3",
36
+ "typescript": "4.7.4",
37
+ "@types/react": "^17.0.24",
38
+ "@types/react-dom": "^17.0.9"
39
+ },
40
+ "main": "lib/index.js",
41
+ "types": "lib/index.d.ts",
42
+ "files": [
43
+ "lib/*",
44
+ "README.md",
45
+ "!*.test.*"
46
+ ],
47
+ "license": "MIT",
48
+ "private": false,
49
+ "sideEffects": false,
50
+ "tsup": {
51
+ "entry": [
52
+ "src/index.ts"
53
+ ],
54
+ "format": "cjs",
55
+ "outDir": "lib"
56
+ }
57
+ }