@ktjs/shared 0.19.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) 2025 kasukabe tsumugi
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.
@@ -0,0 +1,50 @@
1
+ declare const $isArray: (arg: any) => arg is any[];
2
+ declare const $hasOwn: (v: PropertyKey) => boolean;
3
+ declare const $keys: <T>(o: T) => Array<keyof T>;
4
+ declare const $defines: <T>(o: T, properties: PropertyDescriptorMap & ThisType<any>) => T;
5
+ declare const $entries: <T>(o: T) => Array<[keyof T, T[keyof T]]>;
6
+ declare const $isThenable: (o: any) => o is Promise<any>;
7
+
8
+ declare const $throw: (message: string) => never;
9
+
10
+ /**
11
+ * & Remove `bind` because it is shockingly slower than wrapper
12
+ * & `window.document` is safe because it is not configurable and its setter is undefined
13
+ */
14
+ declare const $appendChild: <T extends Node>(node: T) => T;
15
+ declare const originAppend: (...nodes: (Node | string)[]) => void;
16
+ declare const $append: typeof originAppend;
17
+ declare const parseStyle: (style: string | Partial<CSSStyleDeclaration> | undefined) => string;
18
+ type ChangeHandler<T = string> = (value: T, ...args: any[]) => void;
19
+ declare const generateHandler: <T = string>(props: any, key: string) => ChangeHandler<T>;
20
+
21
+ /**
22
+ * Default empty function
23
+ */
24
+ declare const $emptyFn: (...args: any[]) => any;
25
+
26
+ /**
27
+ * Normalize path by joining parts and ensuring leading slash
28
+ */
29
+ declare const normalizePath: (...paths: string[]) => string;
30
+ /**
31
+ * Parse query string into object
32
+ */
33
+ declare const parseQuery: (queryString: string) => Record<string, string>;
34
+ /**
35
+ * Build query string from object
36
+ */
37
+ declare const buildQuery: (query: Record<string, string>) => string;
38
+ /**
39
+ * Substitute params into path pattern
40
+ * @example '/user/:id' + {id: '123'} => '/user/123'
41
+ */
42
+ declare const emplaceParams: (path: string, params: Record<string, string>) => string;
43
+ /**
44
+ * Extract dynamic params from path using pattern
45
+ * @example pattern: '/user/:id', path: '/user/123' => {id: '123'}
46
+ */
47
+ declare const extractParams: (pattern: string, path: string) => Record<string, string> | null;
48
+
49
+ export { $append, $appendChild, $defines, $emptyFn, $entries, $hasOwn, $isArray, $isThenable, $keys, $throw, buildQuery, emplaceParams, extractParams, generateHandler, normalizePath, parseQuery, parseStyle };
50
+ export type { ChangeHandler };
@@ -0,0 +1,183 @@
1
+ var __ktjs_shared__ = (function (exports) {
2
+ 'use strict';
3
+
4
+ // Cached native methods for performance optimization
5
+ const $isArray = Array.isArray;
6
+ const $hasOwn = Object.prototype.hasOwnProperty;
7
+ const $keys = Object.keys;
8
+ const $defines = Object.defineProperties;
9
+ const $entries = Object.entries;
10
+ const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
11
+
12
+ // Error handling utilities
13
+ const $throw = (message) => {
14
+ throw new Error('@ktjs/shared: ' + message);
15
+ };
16
+
17
+ // String manipulation utilities
18
+ /**
19
+ * Default empty function
20
+ */
21
+ const $emptyFn = (() => true);
22
+
23
+ // DOM manipulation utilities
24
+ /**
25
+ * & Remove `bind` because it is shockingly slower than wrapper
26
+ * & `window.document` is safe because it is not configurable and its setter is undefined
27
+ */
28
+ const $appendChild = HTMLElement.prototype.appendChild;
29
+ const originAppend = HTMLElement.prototype.append;
30
+ const $append = // for ie 9/10/11
31
+ typeof originAppend === 'function'
32
+ ? originAppend
33
+ : function (...nodes) {
34
+ if (nodes.length < 50) {
35
+ for (let i = 0; i < nodes.length; i++) {
36
+ const node = nodes[i];
37
+ if (typeof node === 'string') {
38
+ $appendChild.call(this, document.createTextNode(node));
39
+ }
40
+ else {
41
+ $appendChild.call(this, node);
42
+ }
43
+ }
44
+ }
45
+ else {
46
+ const fragment = document.createDocumentFragment();
47
+ for (let i = 0; i < nodes.length; i++) {
48
+ const node = nodes[i];
49
+ if (typeof node === 'string') {
50
+ $appendChild.call(fragment, document.createTextNode(node));
51
+ }
52
+ else {
53
+ $appendChild.call(fragment, node);
54
+ }
55
+ }
56
+ $appendChild.call(this, fragment);
57
+ }
58
+ };
59
+ // Style parsing utilities
60
+ const parseStyle = (style) => {
61
+ if (typeof style === 'string') {
62
+ return style;
63
+ }
64
+ if (style && typeof style === 'object') {
65
+ return Object.entries(style)
66
+ .map(([key, value]) => {
67
+ // Convert camelCase to kebab-case
68
+ const cssKey = key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
69
+ return `${cssKey}: ${value}`;
70
+ })
71
+ .join('; ');
72
+ }
73
+ return '';
74
+ };
75
+ const generateHandler = (props, key) => {
76
+ const handler = props[key];
77
+ if (typeof handler === 'function') {
78
+ return handler;
79
+ }
80
+ else if (handler && typeof handler === 'object' && handler.isKT) {
81
+ return (value) => (handler.value = value);
82
+ }
83
+ return $emptyFn;
84
+ };
85
+
86
+ /**
87
+ * Normalize path by joining parts and ensuring leading slash
88
+ */
89
+ const normalizePath = (...paths) => {
90
+ const p = paths
91
+ .map((p) => p.split('/'))
92
+ .flat()
93
+ .filter(Boolean);
94
+ return '/' + p.join('/');
95
+ };
96
+ /**
97
+ * Parse query string into object
98
+ */
99
+ const parseQuery = (queryString) => {
100
+ const query = {};
101
+ if (!queryString || queryString === '?') {
102
+ return query;
103
+ }
104
+ const params = queryString.replace(/^\?/, '').split('&');
105
+ for (const param of params) {
106
+ const [key, value] = param.split('=');
107
+ if (key) {
108
+ query[decodeURIComponent(key)] = value ? decodeURIComponent(value) : '';
109
+ }
110
+ }
111
+ return query;
112
+ };
113
+ /**
114
+ * Build query string from object
115
+ */
116
+ const buildQuery = (query) => {
117
+ const keys = Object.keys(query);
118
+ if (keys.length === 0)
119
+ return '';
120
+ const params = keys.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`).join('&');
121
+ return `?${params}`;
122
+ };
123
+ /**
124
+ * Substitute params into path pattern
125
+ * @example '/user/:id' + {id: '123'} => '/user/123'
126
+ */
127
+ const emplaceParams = (path, params) => {
128
+ let result = path;
129
+ for (const key in params) {
130
+ result = result.replace(`:${key}`, params[key]);
131
+ }
132
+ return result;
133
+ };
134
+ /**
135
+ * Extract dynamic params from path using pattern
136
+ * @example pattern: '/user/:id', path: '/user/123' => {id: '123'}
137
+ */
138
+ const extractParams = (pattern, path) => {
139
+ const params = {};
140
+ const patternParts = pattern.split('/');
141
+ const pathParts = path.split('/');
142
+ if (patternParts.length !== pathParts.length) {
143
+ return null;
144
+ }
145
+ for (let i = 0; i < patternParts.length; i++) {
146
+ const patternPart = patternParts[i];
147
+ const pathPart = pathParts[i];
148
+ if (patternPart.startsWith(':')) {
149
+ const paramName = patternPart.slice(1);
150
+ params[paramName] = pathPart;
151
+ }
152
+ else if (patternPart !== pathPart) {
153
+ return null;
154
+ }
155
+ }
156
+ return params;
157
+ };
158
+
159
+ // Shared utilities and cached native methods for kt.js framework
160
+ // Re-export all utilities
161
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.19.0' });
162
+
163
+ exports.$append = $append;
164
+ exports.$appendChild = $appendChild;
165
+ exports.$defines = $defines;
166
+ exports.$emptyFn = $emptyFn;
167
+ exports.$entries = $entries;
168
+ exports.$hasOwn = $hasOwn;
169
+ exports.$isArray = $isArray;
170
+ exports.$isThenable = $isThenable;
171
+ exports.$keys = $keys;
172
+ exports.$throw = $throw;
173
+ exports.buildQuery = buildQuery;
174
+ exports.emplaceParams = emplaceParams;
175
+ exports.extractParams = extractParams;
176
+ exports.generateHandler = generateHandler;
177
+ exports.normalizePath = normalizePath;
178
+ exports.parseQuery = parseQuery;
179
+ exports.parseStyle = parseStyle;
180
+
181
+ return exports;
182
+
183
+ })({});
@@ -0,0 +1,195 @@
1
+ var __ktjs_shared__ = (function (exports) {
2
+ 'use strict';
3
+
4
+ // Cached native methods for performance optimization
5
+ var $isArray = Array.isArray;
6
+ var $hasOwn = Object.prototype.hasOwnProperty;
7
+ var $keys = Object.keys;
8
+ var $defines = Object.defineProperties;
9
+ var $entries = Object.entries;
10
+ var $isThenable = function (o) {
11
+ return typeof o === 'object' && o !== null && typeof o.then === 'function';
12
+ };
13
+
14
+ // Error handling utilities
15
+ var $throw = function (message) {
16
+ throw new Error('@ktjs/shared: ' + message);
17
+ };
18
+
19
+ // String manipulation utilities
20
+ /**
21
+ * Default empty function
22
+ */
23
+ var $emptyFn = (function () { return true; });
24
+
25
+ // DOM manipulation utilities
26
+ /**
27
+ * & Remove `bind` because it is shockingly slower than wrapper
28
+ * & `window.document` is safe because it is not configurable and its setter is undefined
29
+ */
30
+ var $appendChild = HTMLElement.prototype.appendChild;
31
+ var originAppend = HTMLElement.prototype.append;
32
+ var $append = // for ie 9/10/11
33
+ typeof originAppend === 'function'
34
+ ? originAppend
35
+ : function () {
36
+ var nodes = [];
37
+ for (var _i = 0; _i < arguments.length; _i++) {
38
+ nodes[_i] = arguments[_i];
39
+ }
40
+ if (nodes.length < 50) {
41
+ for (var i = 0; i < nodes.length; i++) {
42
+ var node = nodes[i];
43
+ if (typeof node === 'string') {
44
+ $appendChild.call(this, document.createTextNode(node));
45
+ }
46
+ else {
47
+ $appendChild.call(this, node);
48
+ }
49
+ }
50
+ }
51
+ else {
52
+ var fragment = document.createDocumentFragment();
53
+ for (var i = 0; i < nodes.length; i++) {
54
+ var node = nodes[i];
55
+ if (typeof node === 'string') {
56
+ $appendChild.call(fragment, document.createTextNode(node));
57
+ }
58
+ else {
59
+ $appendChild.call(fragment, node);
60
+ }
61
+ }
62
+ $appendChild.call(this, fragment);
63
+ }
64
+ };
65
+ // Style parsing utilities
66
+ var parseStyle = function (style) {
67
+ if (typeof style === 'string') {
68
+ return style;
69
+ }
70
+ if (style && typeof style === 'object') {
71
+ return Object.entries(style)
72
+ .map(function (_a) {
73
+ var key = _a[0], value = _a[1];
74
+ // Convert camelCase to kebab-case
75
+ var cssKey = key.replace(/[A-Z]/g, function (m) { return "-".concat(m.toLowerCase()); });
76
+ return "".concat(cssKey, ": ").concat(value);
77
+ })
78
+ .join('; ');
79
+ }
80
+ return '';
81
+ };
82
+ var generateHandler = function (props, key) {
83
+ var handler = props[key];
84
+ if (typeof handler === 'function') {
85
+ return handler;
86
+ }
87
+ else if (handler && typeof handler === 'object' && handler.isKT) {
88
+ return function (value) { return (handler.value = value); };
89
+ }
90
+ return $emptyFn;
91
+ };
92
+
93
+ /**
94
+ * Normalize path by joining parts and ensuring leading slash
95
+ */
96
+ var normalizePath = function () {
97
+ var paths = [];
98
+ for (var _i = 0; _i < arguments.length; _i++) {
99
+ paths[_i] = arguments[_i];
100
+ }
101
+ var p = paths
102
+ .map(function (p) { return p.split('/'); })
103
+ .flat()
104
+ .filter(Boolean);
105
+ return '/' + p.join('/');
106
+ };
107
+ /**
108
+ * Parse query string into object
109
+ */
110
+ var parseQuery = function (queryString) {
111
+ var query = {};
112
+ if (!queryString || queryString === '?') {
113
+ return query;
114
+ }
115
+ var params = queryString.replace(/^\?/, '').split('&');
116
+ for (var _i = 0, params_1 = params; _i < params_1.length; _i++) {
117
+ var param = params_1[_i];
118
+ var _a = param.split('='), key = _a[0], value = _a[1];
119
+ if (key) {
120
+ query[decodeURIComponent(key)] = value ? decodeURIComponent(value) : '';
121
+ }
122
+ }
123
+ return query;
124
+ };
125
+ /**
126
+ * Build query string from object
127
+ */
128
+ var buildQuery = function (query) {
129
+ var keys = Object.keys(query);
130
+ if (keys.length === 0)
131
+ return '';
132
+ var params = keys.map(function (key) { return "".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(query[key])); }).join('&');
133
+ return "?".concat(params);
134
+ };
135
+ /**
136
+ * Substitute params into path pattern
137
+ * @example '/user/:id' + {id: '123'} => '/user/123'
138
+ */
139
+ var emplaceParams = function (path, params) {
140
+ var result = path;
141
+ for (var key in params) {
142
+ result = result.replace(":".concat(key), params[key]);
143
+ }
144
+ return result;
145
+ };
146
+ /**
147
+ * Extract dynamic params from path using pattern
148
+ * @example pattern: '/user/:id', path: '/user/123' => {id: '123'}
149
+ */
150
+ var extractParams = function (pattern, path) {
151
+ var params = {};
152
+ var patternParts = pattern.split('/');
153
+ var pathParts = path.split('/');
154
+ if (patternParts.length !== pathParts.length) {
155
+ return null;
156
+ }
157
+ for (var i = 0; i < patternParts.length; i++) {
158
+ var patternPart = patternParts[i];
159
+ var pathPart = pathParts[i];
160
+ if (patternPart.startsWith(':')) {
161
+ var paramName = patternPart.slice(1);
162
+ params[paramName] = pathPart;
163
+ }
164
+ else if (patternPart !== pathPart) {
165
+ return null;
166
+ }
167
+ }
168
+ return params;
169
+ };
170
+
171
+ // Shared utilities and cached native methods for kt.js framework
172
+ // Re-export all utilities
173
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.19.0' });
174
+
175
+ exports.$append = $append;
176
+ exports.$appendChild = $appendChild;
177
+ exports.$defines = $defines;
178
+ exports.$emptyFn = $emptyFn;
179
+ exports.$entries = $entries;
180
+ exports.$hasOwn = $hasOwn;
181
+ exports.$isArray = $isArray;
182
+ exports.$isThenable = $isThenable;
183
+ exports.$keys = $keys;
184
+ exports.$throw = $throw;
185
+ exports.buildQuery = buildQuery;
186
+ exports.emplaceParams = emplaceParams;
187
+ exports.extractParams = extractParams;
188
+ exports.generateHandler = generateHandler;
189
+ exports.normalizePath = normalizePath;
190
+ exports.parseQuery = parseQuery;
191
+ exports.parseStyle = parseStyle;
192
+
193
+ return exports;
194
+
195
+ })({});
package/dist/index.mjs ADDED
@@ -0,0 +1,160 @@
1
+ // Cached native methods for performance optimization
2
+ const $isArray = Array.isArray;
3
+ const $hasOwn = Object.prototype.hasOwnProperty;
4
+ const $keys = Object.keys;
5
+ const $defines = Object.defineProperties;
6
+ const $entries = Object.entries;
7
+ const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
8
+
9
+ // Error handling utilities
10
+ const $throw = (message) => {
11
+ throw new Error('@ktjs/shared: ' + message);
12
+ };
13
+
14
+ // String manipulation utilities
15
+ /**
16
+ * Default empty function
17
+ */
18
+ const $emptyFn = (() => true);
19
+
20
+ // DOM manipulation utilities
21
+ /**
22
+ * & Remove `bind` because it is shockingly slower than wrapper
23
+ * & `window.document` is safe because it is not configurable and its setter is undefined
24
+ */
25
+ const $appendChild = HTMLElement.prototype.appendChild;
26
+ const originAppend = HTMLElement.prototype.append;
27
+ const $append = // for ie 9/10/11
28
+ typeof originAppend === 'function'
29
+ ? originAppend
30
+ : function (...nodes) {
31
+ if (nodes.length < 50) {
32
+ for (let i = 0; i < nodes.length; i++) {
33
+ const node = nodes[i];
34
+ if (typeof node === 'string') {
35
+ $appendChild.call(this, document.createTextNode(node));
36
+ }
37
+ else {
38
+ $appendChild.call(this, node);
39
+ }
40
+ }
41
+ }
42
+ else {
43
+ const fragment = document.createDocumentFragment();
44
+ for (let i = 0; i < nodes.length; i++) {
45
+ const node = nodes[i];
46
+ if (typeof node === 'string') {
47
+ $appendChild.call(fragment, document.createTextNode(node));
48
+ }
49
+ else {
50
+ $appendChild.call(fragment, node);
51
+ }
52
+ }
53
+ $appendChild.call(this, fragment);
54
+ }
55
+ };
56
+ // Style parsing utilities
57
+ const parseStyle = (style) => {
58
+ if (typeof style === 'string') {
59
+ return style;
60
+ }
61
+ if (style && typeof style === 'object') {
62
+ return Object.entries(style)
63
+ .map(([key, value]) => {
64
+ // Convert camelCase to kebab-case
65
+ const cssKey = key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
66
+ return `${cssKey}: ${value}`;
67
+ })
68
+ .join('; ');
69
+ }
70
+ return '';
71
+ };
72
+ const generateHandler = (props, key) => {
73
+ const handler = props[key];
74
+ if (typeof handler === 'function') {
75
+ return handler;
76
+ }
77
+ else if (handler && typeof handler === 'object' && handler.isKT) {
78
+ return (value) => (handler.value = value);
79
+ }
80
+ return $emptyFn;
81
+ };
82
+
83
+ /**
84
+ * Normalize path by joining parts and ensuring leading slash
85
+ */
86
+ const normalizePath = (...paths) => {
87
+ const p = paths
88
+ .map((p) => p.split('/'))
89
+ .flat()
90
+ .filter(Boolean);
91
+ return '/' + p.join('/');
92
+ };
93
+ /**
94
+ * Parse query string into object
95
+ */
96
+ const parseQuery = (queryString) => {
97
+ const query = {};
98
+ if (!queryString || queryString === '?') {
99
+ return query;
100
+ }
101
+ const params = queryString.replace(/^\?/, '').split('&');
102
+ for (const param of params) {
103
+ const [key, value] = param.split('=');
104
+ if (key) {
105
+ query[decodeURIComponent(key)] = value ? decodeURIComponent(value) : '';
106
+ }
107
+ }
108
+ return query;
109
+ };
110
+ /**
111
+ * Build query string from object
112
+ */
113
+ const buildQuery = (query) => {
114
+ const keys = Object.keys(query);
115
+ if (keys.length === 0)
116
+ return '';
117
+ const params = keys.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`).join('&');
118
+ return `?${params}`;
119
+ };
120
+ /**
121
+ * Substitute params into path pattern
122
+ * @example '/user/:id' + {id: '123'} => '/user/123'
123
+ */
124
+ const emplaceParams = (path, params) => {
125
+ let result = path;
126
+ for (const key in params) {
127
+ result = result.replace(`:${key}`, params[key]);
128
+ }
129
+ return result;
130
+ };
131
+ /**
132
+ * Extract dynamic params from path using pattern
133
+ * @example pattern: '/user/:id', path: '/user/123' => {id: '123'}
134
+ */
135
+ const extractParams = (pattern, path) => {
136
+ const params = {};
137
+ const patternParts = pattern.split('/');
138
+ const pathParts = path.split('/');
139
+ if (patternParts.length !== pathParts.length) {
140
+ return null;
141
+ }
142
+ for (let i = 0; i < patternParts.length; i++) {
143
+ const patternPart = patternParts[i];
144
+ const pathPart = pathParts[i];
145
+ if (patternPart.startsWith(':')) {
146
+ const paramName = patternPart.slice(1);
147
+ params[paramName] = pathPart;
148
+ }
149
+ else if (patternPart !== pathPart) {
150
+ return null;
151
+ }
152
+ }
153
+ return params;
154
+ };
155
+
156
+ // Shared utilities and cached native methods for kt.js framework
157
+ // Re-export all utilities
158
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.19.0' });
159
+
160
+ export { $append, $appendChild, $defines, $emptyFn, $entries, $hasOwn, $isArray, $isThenable, $keys, $throw, buildQuery, emplaceParams, extractParams, generateHandler, normalizePath, parseQuery, parseStyle };
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@ktjs/shared",
3
+ "version": "0.19.0",
4
+ "description": "Shared utilities and cached native methods for kt.js framework",
5
+ "type": "module",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "default": "./dist/index.mjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "keywords": [
19
+ "utilities",
20
+ "shared",
21
+ "framework",
22
+ "web",
23
+ "tools"
24
+ ],
25
+ "license": "MIT",
26
+ "author": {
27
+ "name": "Kasukabe Tsumugi",
28
+ "email": "futami16237@gmail.com"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/baendlorel/kt.js",
33
+ "directory": "packages/shared"
34
+ },
35
+ "scripts": {
36
+ "build": "rollup -c rollup.config.mjs",
37
+ "dev": "rollup -c rollup.config.mjs -w"
38
+ }
39
+ }