pulse-js-framework 1.4.7 → 1.4.9
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 +70 -5
- package/cli/dev.js +24 -1
- package/cli/lint.js +117 -0
- package/compiler/index.js +33 -3
- package/compiler/sourcemap.js +360 -0
- package/compiler/transformer.js +108 -2
- package/package.json +4 -2
- package/runtime/router.js +374 -8
- package/types/hmr.d.ts +112 -0
- package/types/index.d.ts +25 -1
- package/types/router.d.ts +89 -0
- package/types/sourcemap.d.ts +126 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulse Source Map Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates V3 source maps for .pulse files compiled to JavaScript.
|
|
5
|
+
* Enables debugging of original .pulse code in browser devtools.
|
|
6
|
+
*
|
|
7
|
+
* @module pulse-js-framework/compiler/sourcemap
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Base64 VLQ encoding for source map mappings
|
|
12
|
+
* VLQ (Variable Length Quantity) is used to encode position data compactly
|
|
13
|
+
*/
|
|
14
|
+
const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Encode a number as VLQ base64
|
|
18
|
+
* @param {number} value - Number to encode (can be negative)
|
|
19
|
+
* @returns {string} VLQ encoded string
|
|
20
|
+
*/
|
|
21
|
+
export function encodeVLQ(value) {
|
|
22
|
+
let encoded = '';
|
|
23
|
+
// Convert to unsigned and add sign bit
|
|
24
|
+
let vlq = value < 0 ? ((-value) << 1) + 1 : (value << 1);
|
|
25
|
+
|
|
26
|
+
do {
|
|
27
|
+
let digit = vlq & 0x1F; // 5 bits
|
|
28
|
+
vlq >>>= 5;
|
|
29
|
+
if (vlq > 0) {
|
|
30
|
+
digit |= 0x20; // Set continuation bit
|
|
31
|
+
}
|
|
32
|
+
encoded += BASE64_CHARS[digit];
|
|
33
|
+
} while (vlq > 0);
|
|
34
|
+
|
|
35
|
+
return encoded;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Source Map Generator class
|
|
40
|
+
* Tracks mappings between generated and original source positions
|
|
41
|
+
*/
|
|
42
|
+
export class SourceMapGenerator {
|
|
43
|
+
/**
|
|
44
|
+
* @param {Object} options
|
|
45
|
+
* @param {string} options.file - Generated file name
|
|
46
|
+
* @param {string} options.sourceRoot - Root URL for source files
|
|
47
|
+
*/
|
|
48
|
+
constructor(options = {}) {
|
|
49
|
+
this.file = options.file || '';
|
|
50
|
+
this.sourceRoot = options.sourceRoot || '';
|
|
51
|
+
this.sources = [];
|
|
52
|
+
this.sourcesContent = [];
|
|
53
|
+
this.names = [];
|
|
54
|
+
this.mappings = [];
|
|
55
|
+
|
|
56
|
+
// Current state for relative encoding
|
|
57
|
+
this._lastGeneratedLine = 0;
|
|
58
|
+
this._lastGeneratedColumn = 0;
|
|
59
|
+
this._lastSourceIndex = 0;
|
|
60
|
+
this._lastSourceLine = 0;
|
|
61
|
+
this._lastSourceColumn = 0;
|
|
62
|
+
this._lastNameIndex = 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Add a source file
|
|
67
|
+
* @param {string} source - Source file path
|
|
68
|
+
* @param {string} content - Source file content (optional)
|
|
69
|
+
* @returns {number} Source index
|
|
70
|
+
*/
|
|
71
|
+
addSource(source, content = null) {
|
|
72
|
+
let index = this.sources.indexOf(source);
|
|
73
|
+
if (index === -1) {
|
|
74
|
+
index = this.sources.length;
|
|
75
|
+
this.sources.push(source);
|
|
76
|
+
this.sourcesContent.push(content);
|
|
77
|
+
}
|
|
78
|
+
return index;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Add a name (identifier) to the names array
|
|
83
|
+
* @param {string} name - Identifier name
|
|
84
|
+
* @returns {number} Name index
|
|
85
|
+
*/
|
|
86
|
+
addName(name) {
|
|
87
|
+
let index = this.names.indexOf(name);
|
|
88
|
+
if (index === -1) {
|
|
89
|
+
index = this.names.length;
|
|
90
|
+
this.names.push(name);
|
|
91
|
+
}
|
|
92
|
+
return index;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Add a mapping between generated and original positions
|
|
97
|
+
* @param {Object} mapping
|
|
98
|
+
* @param {Object} mapping.generated - Generated position {line, column}
|
|
99
|
+
* @param {Object} mapping.original - Original position {line, column} (optional)
|
|
100
|
+
* @param {string} mapping.source - Source file path (required if original provided)
|
|
101
|
+
* @param {string} mapping.name - Original identifier name (optional)
|
|
102
|
+
*/
|
|
103
|
+
addMapping(mapping) {
|
|
104
|
+
const { generated, original, source, name } = mapping;
|
|
105
|
+
|
|
106
|
+
// Ensure mappings array has enough lines
|
|
107
|
+
while (this.mappings.length <= generated.line) {
|
|
108
|
+
this.mappings.push([]);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const segment = {
|
|
112
|
+
generatedColumn: generated.column,
|
|
113
|
+
sourceIndex: source ? this.addSource(source) : null,
|
|
114
|
+
originalLine: original?.line ?? null,
|
|
115
|
+
originalColumn: original?.column ?? null,
|
|
116
|
+
nameIndex: name ? this.addName(name) : null
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
this.mappings[generated.line].push(segment);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Encode all mappings as VLQ string
|
|
124
|
+
* @returns {string} Encoded mappings
|
|
125
|
+
*/
|
|
126
|
+
_encodeMappings() {
|
|
127
|
+
let previousGeneratedColumn = 0;
|
|
128
|
+
let previousSourceIndex = 0;
|
|
129
|
+
let previousSourceLine = 0;
|
|
130
|
+
let previousSourceColumn = 0;
|
|
131
|
+
let previousNameIndex = 0;
|
|
132
|
+
|
|
133
|
+
const lines = [];
|
|
134
|
+
|
|
135
|
+
for (const line of this.mappings) {
|
|
136
|
+
if (line.length === 0) {
|
|
137
|
+
lines.push('');
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Sort segments by generated column
|
|
142
|
+
line.sort((a, b) => a.generatedColumn - b.generatedColumn);
|
|
143
|
+
|
|
144
|
+
const segments = [];
|
|
145
|
+
previousGeneratedColumn = 0; // Reset column for each line
|
|
146
|
+
|
|
147
|
+
for (const segment of line) {
|
|
148
|
+
let encoded = '';
|
|
149
|
+
|
|
150
|
+
// 1. Generated column (relative to previous segment in same line)
|
|
151
|
+
encoded += encodeVLQ(segment.generatedColumn - previousGeneratedColumn);
|
|
152
|
+
previousGeneratedColumn = segment.generatedColumn;
|
|
153
|
+
|
|
154
|
+
// If we have source info
|
|
155
|
+
if (segment.sourceIndex !== null) {
|
|
156
|
+
// 2. Source file index (relative)
|
|
157
|
+
encoded += encodeVLQ(segment.sourceIndex - previousSourceIndex);
|
|
158
|
+
previousSourceIndex = segment.sourceIndex;
|
|
159
|
+
|
|
160
|
+
// 3. Original line (relative, 0-based in source maps)
|
|
161
|
+
encoded += encodeVLQ(segment.originalLine - previousSourceLine);
|
|
162
|
+
previousSourceLine = segment.originalLine;
|
|
163
|
+
|
|
164
|
+
// 4. Original column (relative)
|
|
165
|
+
encoded += encodeVLQ(segment.originalColumn - previousSourceColumn);
|
|
166
|
+
previousSourceColumn = segment.originalColumn;
|
|
167
|
+
|
|
168
|
+
// 5. Optional: name index (relative)
|
|
169
|
+
if (segment.nameIndex !== null) {
|
|
170
|
+
encoded += encodeVLQ(segment.nameIndex - previousNameIndex);
|
|
171
|
+
previousNameIndex = segment.nameIndex;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
segments.push(encoded);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
lines.push(segments.join(','));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return lines.join(';');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Generate the source map object
|
|
186
|
+
* @returns {Object} Source map object (V3 format)
|
|
187
|
+
*/
|
|
188
|
+
toJSON() {
|
|
189
|
+
return {
|
|
190
|
+
version: 3,
|
|
191
|
+
file: this.file,
|
|
192
|
+
sourceRoot: this.sourceRoot,
|
|
193
|
+
sources: this.sources,
|
|
194
|
+
sourcesContent: this.sourcesContent,
|
|
195
|
+
names: this.names,
|
|
196
|
+
mappings: this._encodeMappings()
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Generate source map as JSON string
|
|
202
|
+
* @returns {string} JSON string
|
|
203
|
+
*/
|
|
204
|
+
toString() {
|
|
205
|
+
return JSON.stringify(this.toJSON());
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Generate inline source map comment
|
|
210
|
+
* @returns {string} Comment with base64 encoded source map
|
|
211
|
+
*/
|
|
212
|
+
toComment() {
|
|
213
|
+
const base64 = typeof btoa === 'function'
|
|
214
|
+
? btoa(this.toString())
|
|
215
|
+
: Buffer.from(this.toString()).toString('base64');
|
|
216
|
+
return `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64}`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Generate external source map URL comment
|
|
221
|
+
* @param {string} url - URL to source map file
|
|
222
|
+
* @returns {string} Comment with source map URL
|
|
223
|
+
*/
|
|
224
|
+
static toURLComment(url) {
|
|
225
|
+
return `//# sourceMappingURL=${url}`;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Source Map Consumer - parse and query source maps
|
|
231
|
+
* Useful for error stack trace translation
|
|
232
|
+
*/
|
|
233
|
+
export class SourceMapConsumer {
|
|
234
|
+
/**
|
|
235
|
+
* @param {Object|string} sourceMap - Source map object or JSON string
|
|
236
|
+
*/
|
|
237
|
+
constructor(sourceMap) {
|
|
238
|
+
this.map = typeof sourceMap === 'string' ? JSON.parse(sourceMap) : sourceMap;
|
|
239
|
+
this._decodedMappings = null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Decode VLQ string to numbers
|
|
244
|
+
* @param {string} str - VLQ encoded string
|
|
245
|
+
* @returns {number[]} Decoded numbers
|
|
246
|
+
*/
|
|
247
|
+
static decodeVLQ(str) {
|
|
248
|
+
const values = [];
|
|
249
|
+
let value = 0;
|
|
250
|
+
let shift = 0;
|
|
251
|
+
|
|
252
|
+
for (const char of str) {
|
|
253
|
+
const digit = BASE64_CHARS.indexOf(char);
|
|
254
|
+
if (digit === -1) continue;
|
|
255
|
+
|
|
256
|
+
value += (digit & 0x1F) << shift;
|
|
257
|
+
|
|
258
|
+
if (digit & 0x20) {
|
|
259
|
+
shift += 5;
|
|
260
|
+
} else {
|
|
261
|
+
// Check sign bit
|
|
262
|
+
const negative = value & 1;
|
|
263
|
+
value >>= 1;
|
|
264
|
+
values.push(negative ? -value : value);
|
|
265
|
+
value = 0;
|
|
266
|
+
shift = 0;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return values;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Get original position for a generated position
|
|
275
|
+
* @param {Object} position - Generated position {line, column}
|
|
276
|
+
* @returns {Object|null} Original position or null
|
|
277
|
+
*/
|
|
278
|
+
originalPositionFor(position) {
|
|
279
|
+
this._ensureDecoded();
|
|
280
|
+
|
|
281
|
+
const { line, column } = position;
|
|
282
|
+
const lineData = this._decodedMappings[line];
|
|
283
|
+
|
|
284
|
+
if (!lineData) return null;
|
|
285
|
+
|
|
286
|
+
// Find the closest mapping at or before this column
|
|
287
|
+
let closest = null;
|
|
288
|
+
for (const mapping of lineData) {
|
|
289
|
+
if (mapping.generatedColumn <= column) {
|
|
290
|
+
closest = mapping;
|
|
291
|
+
} else {
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (!closest || closest.sourceIndex === null) return null;
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
source: this.map.sources[closest.sourceIndex],
|
|
300
|
+
line: closest.originalLine,
|
|
301
|
+
column: closest.originalColumn,
|
|
302
|
+
name: closest.nameIndex !== null ? this.map.names[closest.nameIndex] : null
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Decode mappings lazily
|
|
308
|
+
*/
|
|
309
|
+
_ensureDecoded() {
|
|
310
|
+
if (this._decodedMappings) return;
|
|
311
|
+
|
|
312
|
+
this._decodedMappings = [];
|
|
313
|
+
const lines = this.map.mappings.split(';');
|
|
314
|
+
|
|
315
|
+
let sourceIndex = 0;
|
|
316
|
+
let sourceLine = 0;
|
|
317
|
+
let sourceColumn = 0;
|
|
318
|
+
let nameIndex = 0;
|
|
319
|
+
|
|
320
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
321
|
+
const line = lines[lineIndex];
|
|
322
|
+
const segments = line.split(',').filter(s => s);
|
|
323
|
+
const lineData = [];
|
|
324
|
+
let generatedColumn = 0;
|
|
325
|
+
|
|
326
|
+
for (const segment of segments) {
|
|
327
|
+
const values = SourceMapConsumer.decodeVLQ(segment);
|
|
328
|
+
|
|
329
|
+
generatedColumn += values[0];
|
|
330
|
+
|
|
331
|
+
const mapping = { generatedColumn };
|
|
332
|
+
|
|
333
|
+
if (values.length >= 4) {
|
|
334
|
+
sourceIndex += values[1];
|
|
335
|
+
sourceLine += values[2];
|
|
336
|
+
sourceColumn += values[3];
|
|
337
|
+
|
|
338
|
+
mapping.sourceIndex = sourceIndex;
|
|
339
|
+
mapping.originalLine = sourceLine;
|
|
340
|
+
mapping.originalColumn = sourceColumn;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (values.length >= 5) {
|
|
344
|
+
nameIndex += values[4];
|
|
345
|
+
mapping.nameIndex = nameIndex;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
lineData.push(mapping);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
this._decodedMappings.push(lineData);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export default {
|
|
357
|
+
SourceMapGenerator,
|
|
358
|
+
SourceMapConsumer,
|
|
359
|
+
encodeVLQ
|
|
360
|
+
};
|
package/compiler/transformer.js
CHANGED
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
* - Import statement support
|
|
8
8
|
* - Slot-based component composition
|
|
9
9
|
* - CSS scoping with unique class prefixes
|
|
10
|
+
* - Source map generation
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
import { NodeType } from './parser.js';
|
|
14
|
+
import { SourceMapGenerator } from './sourcemap.js';
|
|
13
15
|
|
|
14
16
|
/** Generate a unique scope ID for CSS scoping */
|
|
15
17
|
const generateScopeId = () => 'p' + Math.random().toString(36).substring(2, 8);
|
|
@@ -29,13 +31,92 @@ const STATEMENT_TOKEN_TYPES = new Set(['IF', 'FOR', 'EACH']);
|
|
|
29
31
|
export class Transformer {
|
|
30
32
|
constructor(ast, options = {}) {
|
|
31
33
|
this.ast = ast;
|
|
32
|
-
this.options = {
|
|
34
|
+
this.options = {
|
|
35
|
+
runtime: 'pulse-js-framework/runtime',
|
|
36
|
+
minify: false,
|
|
37
|
+
scopeStyles: true,
|
|
38
|
+
sourceMap: false, // Enable source map generation
|
|
39
|
+
sourceFileName: null, // Original .pulse file name
|
|
40
|
+
sourceContent: null, // Original source content (for inline source maps)
|
|
41
|
+
...options
|
|
42
|
+
};
|
|
33
43
|
this.stateVars = new Set();
|
|
34
44
|
this.propVars = new Set();
|
|
35
45
|
this.propDefaults = new Map();
|
|
36
46
|
this.actionNames = new Set();
|
|
37
47
|
this.importedComponents = new Map();
|
|
38
48
|
this.scopeId = this.options.scopeStyles ? generateScopeId() : null;
|
|
49
|
+
|
|
50
|
+
// Source map tracking
|
|
51
|
+
this.sourceMap = null;
|
|
52
|
+
this._currentLine = 0;
|
|
53
|
+
this._currentColumn = 0;
|
|
54
|
+
|
|
55
|
+
// Initialize source map generator if enabled
|
|
56
|
+
if (this.options.sourceMap) {
|
|
57
|
+
this.sourceMap = new SourceMapGenerator({
|
|
58
|
+
file: this.options.sourceFileName?.replace('.pulse', '.js') || 'output.js'
|
|
59
|
+
});
|
|
60
|
+
if (this.options.sourceFileName) {
|
|
61
|
+
this.sourceMap.addSource(
|
|
62
|
+
this.options.sourceFileName,
|
|
63
|
+
this.options.sourceContent
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Add a mapping to the source map
|
|
71
|
+
* @param {Object} original - Original position {line, column} (1-based)
|
|
72
|
+
* @param {string} name - Optional identifier name
|
|
73
|
+
*/
|
|
74
|
+
_addMapping(original, name = null) {
|
|
75
|
+
if (!this.sourceMap || !original) return;
|
|
76
|
+
|
|
77
|
+
this.sourceMap.addMapping({
|
|
78
|
+
generated: {
|
|
79
|
+
line: this._currentLine,
|
|
80
|
+
column: this._currentColumn
|
|
81
|
+
},
|
|
82
|
+
original: {
|
|
83
|
+
line: original.line - 1, // Convert to 0-based
|
|
84
|
+
column: original.column - 1
|
|
85
|
+
},
|
|
86
|
+
source: this.options.sourceFileName,
|
|
87
|
+
name
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Track output position when writing code
|
|
93
|
+
* @param {string} code - Generated code
|
|
94
|
+
* @returns {string} The same code (for chaining)
|
|
95
|
+
*/
|
|
96
|
+
_trackCode(code) {
|
|
97
|
+
for (const char of code) {
|
|
98
|
+
if (char === '\n') {
|
|
99
|
+
this._currentLine++;
|
|
100
|
+
this._currentColumn = 0;
|
|
101
|
+
} else {
|
|
102
|
+
this._currentColumn++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return code;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Write code with optional source mapping
|
|
110
|
+
* @param {string} code - Code to write
|
|
111
|
+
* @param {Object} original - Original position {line, column}
|
|
112
|
+
* @param {string} name - Optional identifier name
|
|
113
|
+
* @returns {string} The code
|
|
114
|
+
*/
|
|
115
|
+
_emit(code, original = null, name = null) {
|
|
116
|
+
if (original) {
|
|
117
|
+
this._addMapping(original, name);
|
|
118
|
+
}
|
|
119
|
+
return this._trackCode(code);
|
|
39
120
|
}
|
|
40
121
|
|
|
41
122
|
/**
|
|
@@ -100,7 +181,32 @@ export class Transformer {
|
|
|
100
181
|
// Component export
|
|
101
182
|
parts.push(this.generateExport());
|
|
102
183
|
|
|
103
|
-
|
|
184
|
+
const code = parts.filter(Boolean).join('\n\n');
|
|
185
|
+
|
|
186
|
+
// Track the generated code for source map positions
|
|
187
|
+
if (this.sourceMap) {
|
|
188
|
+
this._trackCode(code);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return code;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Transform AST and return result with optional source map
|
|
196
|
+
* @returns {Object} Result with code and optional sourceMap
|
|
197
|
+
*/
|
|
198
|
+
transformWithSourceMap() {
|
|
199
|
+
const code = this.transform();
|
|
200
|
+
|
|
201
|
+
if (!this.sourceMap) {
|
|
202
|
+
return { code, sourceMap: null };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
code,
|
|
207
|
+
sourceMap: this.sourceMap.toJSON(),
|
|
208
|
+
sourceMapComment: this.sourceMap.toComment()
|
|
209
|
+
};
|
|
104
210
|
}
|
|
105
211
|
|
|
106
212
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pulse-js-framework",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.9",
|
|
4
4
|
"description": "A declarative DOM framework with CSS selector-based structure and reactive pulsations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"default": "./runtime/logger.js"
|
|
43
43
|
},
|
|
44
44
|
"./runtime/hmr": {
|
|
45
|
+
"types": "./types/hmr.d.ts",
|
|
45
46
|
"default": "./runtime/hmr.js"
|
|
46
47
|
},
|
|
47
48
|
"./compiler": {
|
|
@@ -70,8 +71,9 @@
|
|
|
70
71
|
"LICENSE"
|
|
71
72
|
],
|
|
72
73
|
"scripts": {
|
|
73
|
-
"test": "npm run test:compiler && npm run test:pulse && npm run test:dom && npm run test:router && npm run test:store && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze",
|
|
74
|
+
"test": "npm run test:compiler && npm run test:sourcemap && npm run test:pulse && npm run test:dom && npm run test:router && npm run test:store && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze",
|
|
74
75
|
"test:compiler": "node test/compiler.test.js",
|
|
76
|
+
"test:sourcemap": "node test/sourcemap.test.js",
|
|
75
77
|
"test:pulse": "node test/pulse.test.js",
|
|
76
78
|
"test:dom": "node test/dom.test.js",
|
|
77
79
|
"test:router": "node test/router.test.js",
|