ripple 0.3.13 → 0.3.15

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/package.json +5 -30
  3. package/src/runtime/array.js +38 -38
  4. package/src/runtime/create-subscriber.js +2 -2
  5. package/src/runtime/internal/client/bindings.js +4 -6
  6. package/src/runtime/internal/client/events.js +8 -3
  7. package/src/runtime/internal/client/hmr.js +5 -17
  8. package/src/runtime/internal/client/runtime.js +1 -0
  9. package/src/runtime/internal/server/blocks.js +7 -9
  10. package/src/runtime/internal/server/index.js +14 -22
  11. package/src/runtime/media-query.js +34 -33
  12. package/src/runtime/object.js +7 -10
  13. package/src/runtime/proxy.js +2 -3
  14. package/src/runtime/reactive-value.js +23 -21
  15. package/src/utils/ast.js +1 -1
  16. package/src/utils/attributes.js +43 -0
  17. package/src/utils/builders.js +2 -2
  18. package/tests/client/basic/basic.components.test.rsrx +103 -1
  19. package/tests/client/basic/basic.errors.test.rsrx +1 -1
  20. package/tests/client/basic/basic.styling.test.rsrx +1 -1
  21. package/tests/client/compiler/compiler.assignments.test.rsrx +1 -1
  22. package/tests/client/compiler/compiler.attributes.test.rsrx +1 -1
  23. package/tests/client/compiler/compiler.basic.test.rsrx +51 -14
  24. package/tests/client/compiler/compiler.tracked-access.test.rsrx +1 -1
  25. package/tests/client/compiler/compiler.try-in-function.test.rsrx +1 -1
  26. package/tests/client/compiler/compiler.typescript.test.rsrx +1 -1
  27. package/tests/client/css/global-additional-cases.test.rsrx +1 -1
  28. package/tests/client/css/global-advanced-selectors.test.rsrx +1 -1
  29. package/tests/client/css/global-at-rules.test.rsrx +1 -1
  30. package/tests/client/css/global-basic.test.rsrx +1 -1
  31. package/tests/client/css/global-classes-ids.test.rsrx +1 -1
  32. package/tests/client/css/global-combinators.test.rsrx +1 -1
  33. package/tests/client/css/global-complex-nesting.test.rsrx +1 -1
  34. package/tests/client/css/global-edge-cases.test.rsrx +1 -1
  35. package/tests/client/css/global-keyframes.test.rsrx +1 -1
  36. package/tests/client/css/global-nested.test.rsrx +1 -1
  37. package/tests/client/css/global-pseudo.test.rsrx +1 -1
  38. package/tests/client/css/global-scoping.test.rsrx +1 -1
  39. package/tests/client/css/style-identifier.test.rsrx +1 -1
  40. package/tests/client/return.test.rsrx +1 -1
  41. package/tests/hydration/build-components.js +1 -1
  42. package/tests/server/basic.components.test.rsrx +114 -0
  43. package/tests/server/compiler.test.rsrx +38 -1
  44. package/tests/server/style-identifier.test.rsrx +1 -1
  45. package/tests/setup-server.js +1 -1
  46. package/tests/utils/compiler-compat-config.test.js +1 -1
  47. package/types/index.d.ts +1 -1
  48. package/src/compiler/comment-utils.js +0 -91
  49. package/src/compiler/errors.js +0 -77
  50. package/src/compiler/identifier-utils.js +0 -80
  51. package/src/compiler/index.d.ts +0 -127
  52. package/src/compiler/index.js +0 -89
  53. package/src/compiler/phases/1-parse/index.js +0 -3007
  54. package/src/compiler/phases/1-parse/style.js +0 -704
  55. package/src/compiler/phases/2-analyze/css-analyze.js +0 -160
  56. package/src/compiler/phases/2-analyze/index.js +0 -2208
  57. package/src/compiler/phases/2-analyze/prune.js +0 -1131
  58. package/src/compiler/phases/2-analyze/validation.js +0 -168
  59. package/src/compiler/phases/3-transform/client/index.js +0 -5264
  60. package/src/compiler/phases/3-transform/segments.js +0 -2125
  61. package/src/compiler/phases/3-transform/server/index.js +0 -1749
  62. package/src/compiler/phases/3-transform/stylesheet.js +0 -545
  63. package/src/compiler/scope.js +0 -476
  64. package/src/compiler/source-map-utils.js +0 -358
  65. package/src/compiler/types/acorn.d.ts +0 -11
  66. package/src/compiler/types/estree-jsx.d.ts +0 -11
  67. package/src/compiler/types/estree.d.ts +0 -11
  68. package/src/compiler/types/index.d.ts +0 -1411
  69. package/src/compiler/types/parse.d.ts +0 -1723
  70. package/src/compiler/utils.js +0 -1258
@@ -1,358 +0,0 @@
1
- /**
2
- @import { PostProcessingChanges, LineOffsets } from './phases/3-transform/client/index.js';
3
- @import * as AST from 'estree';
4
- @import { CodeMapping } from 'ripple/compiler';
5
- @import { CodeMapping as VolarCodeMapping } from '@volar/language-core';
6
- @import { RawSourceMap } from 'source-map';
7
- */
8
-
9
- /**
10
- @typedef {{
11
- line: number,
12
- column: number,
13
- end_line: number,
14
- end_column: number,
15
- code: string,
16
- metadata: {
17
- css?: AST.Element['metadata']['css']
18
- },
19
- }} CodePosition
20
-
21
- @typedef {Map<string, CodePosition[]>} CodeToGeneratedMap
22
- @typedef {Map<string, {line: number, column: number}[]>} GeneratedToSourceMap
23
- */
24
-
25
- import { decode } from '@jridgewell/sourcemap-codec';
26
-
27
- /** @type {VolarCodeMapping['data']} */
28
- export const mapping_data = {
29
- verification: true,
30
- completion: true,
31
- semantic: true,
32
- navigation: true,
33
- structure: true,
34
- format: false,
35
- };
36
-
37
- /** @type {Partial<VolarCodeMapping['data']>} */
38
- export const mapping_data_verify_only = {
39
- verification: true,
40
- };
41
-
42
- /** @type {Partial<VolarCodeMapping['data']>} */
43
- export const mapping_data_verify_complete = {
44
- verification: true,
45
- completion: true,
46
- };
47
-
48
- /**
49
- * Convert byte offset to line/column
50
- * @param {number} offset
51
- * @param {LineOffsets} line_offsets
52
- * @returns {{ line: number, column: number }}
53
- */
54
- export const offset_to_line_col = (offset, line_offsets) => {
55
- // Binary search
56
- let left = 0;
57
- let right = line_offsets.length - 1;
58
- let line = 1;
59
-
60
- while (left <= right) {
61
- const mid = Math.floor((left + right) / 2);
62
- if (
63
- offset >= line_offsets[mid] &&
64
- (mid === line_offsets.length - 1 || offset < line_offsets[mid + 1])
65
- ) {
66
- line = mid + 1;
67
- break;
68
- } else if (offset < line_offsets[mid]) {
69
- right = mid - 1;
70
- } else {
71
- left = mid + 1;
72
- }
73
- }
74
-
75
- const column = offset - line_offsets[line - 1];
76
- return { line, column };
77
- };
78
-
79
- /**
80
- * Build a source-to-generated position lookup map from an esrap source map
81
- * Applies post-processing adjustments during map building for efficiency
82
- * @param {RawSourceMap} source_map - The source map object from esrap (v3 format)
83
- * @param {PostProcessingChanges} post_processing_changes - Optional post-processing changes to apply
84
- * @param {LineOffsets} line_offsets - Pre-computed line offsets array
85
- * @param {string} generated_code - The final generated code (after post-processing)
86
- * @returns {[CodeToGeneratedMap, GeneratedToSourceMap]} Tuple of [source-to-generated map, generated-to-source map]
87
- */
88
- export function build_src_to_gen_map(
89
- source_map,
90
- post_processing_changes,
91
- line_offsets,
92
- generated_code,
93
- ) {
94
- /** @type {CodeToGeneratedMap} */
95
- const map = new Map();
96
- /** @type {GeneratedToSourceMap} */
97
- const reverse_map = new Map();
98
-
99
- // Decode the VLQ-encoded mappings string
100
- const decoded = decode(source_map.mappings);
101
-
102
- /**
103
- * Convert line/column position to byte offset
104
- * @param {number} line - 1-based line number
105
- * @param {number} column - 0-based column number
106
- * @returns {number} Byte offset
107
- */
108
- const line_col_to_byte_offset = (line, column) => {
109
- return line_offsets[line - 1] + column;
110
- };
111
-
112
- // Apply post-processing adjustments to all segments first
113
- /** @type {Array<Array<{line: number, column: number, sourceLine: number, sourceColumn: number}>>} */
114
- const adjusted_segments = [];
115
-
116
- for (let generated_line = 0; generated_line < decoded.length; generated_line++) {
117
- const line = decoded[generated_line];
118
- adjusted_segments[generated_line] = [];
119
-
120
- for (const segment of line) {
121
- if (segment.length >= 4) {
122
- let adjusted_line = generated_line + 1;
123
- let adjusted_column = segment[0];
124
-
125
- if (post_processing_changes) {
126
- const line_change = post_processing_changes.get(adjusted_line);
127
-
128
- if (line_change) {
129
- const pos_offset = line_col_to_byte_offset(adjusted_line, adjusted_column);
130
-
131
- if (pos_offset >= line_change.offset) {
132
- const adjusted_offset = pos_offset + line_change.delta;
133
- const adjusted_pos = offset_to_line_col(adjusted_offset, line_offsets);
134
- adjusted_line = adjusted_pos.line;
135
- adjusted_column = adjusted_pos.column;
136
- }
137
- }
138
- }
139
-
140
- adjusted_segments[generated_line].push({
141
- line: adjusted_line,
142
- column: adjusted_column,
143
- sourceLine: /** @type {number} */ (segment[2]),
144
- sourceColumn: /** @type {number} */ (segment[3]),
145
- });
146
- }
147
- }
148
- }
149
-
150
- // Now build the map using adjusted positions
151
- for (let line_idx = 0; line_idx < adjusted_segments.length; line_idx++) {
152
- const line_segments = adjusted_segments[line_idx];
153
-
154
- for (let seg_idx = 0; seg_idx < line_segments.length; seg_idx++) {
155
- const segment = line_segments[seg_idx];
156
- const line = segment.line;
157
- const column = segment.column;
158
-
159
- // Determine end position using next segment
160
- let end_line = line;
161
- let end_column = column;
162
-
163
- // Look for next segment to determine end position
164
- if (seg_idx + 1 < line_segments.length) {
165
- // Next segment on same line
166
- const next_segment = line_segments[seg_idx + 1];
167
- end_line = next_segment.line;
168
- end_column = next_segment.column;
169
- } else if (
170
- line_idx + 1 < adjusted_segments.length &&
171
- adjusted_segments[line_idx + 1].length > 0
172
- ) {
173
- // Look at first segment of next line
174
- const next_segment = adjusted_segments[line_idx + 1][0];
175
- end_line = next_segment.line;
176
- end_column = next_segment.column;
177
- }
178
-
179
- // Extract code snippet
180
- const start_offset = line_col_to_byte_offset(line, column);
181
- const end_offset = line_col_to_byte_offset(end_line, end_column);
182
- const code_snippet = generated_code.slice(start_offset, end_offset);
183
-
184
- // Create key from source position (1-indexed line, 0-indexed column)
185
- segment.sourceLine += 1;
186
- const key = `${segment.sourceLine}:${segment.sourceColumn}`;
187
-
188
- // Store adjusted generated position with code snippet
189
- const gen_pos = { line, column, end_line, end_column, code: code_snippet, metadata: {} };
190
-
191
- if (!map.has(key)) {
192
- map.set(key, []);
193
- }
194
- /** @type {CodePosition[]} */ (map.get(key)).push(gen_pos);
195
-
196
- // Store reverse mapping (generated to source)
197
- const gen_key = `${gen_pos.line}:${gen_pos.column}`;
198
-
199
- if (!reverse_map.has(gen_key)) {
200
- reverse_map.set(gen_key, []);
201
- }
202
- reverse_map.get(gen_key)?.push({
203
- line: segment.sourceLine,
204
- column: segment.sourceColumn,
205
- });
206
- }
207
- }
208
-
209
- return [map, reverse_map];
210
- }
211
-
212
- /**
213
- * Look up generated position for a given source position if it exists
214
- * @param {number} src_line - 1-based line number in source
215
- * @param {number} src_column - 0-based column number in source
216
- * @param {CodeToGeneratedMap} src_to_gen_map - Lookup map
217
- * @returns {CodePosition | Error} Generated position
218
- */
219
- function maybe_get_generated_position(src_line, src_column, src_to_gen_map) {
220
- const key = `${src_line}:${src_column}`;
221
- const positions = src_to_gen_map.get(key);
222
-
223
- if (!positions || positions.length === 0) {
224
- return new Error(`No source map entry for position "${src_line}:${src_column}"`);
225
- }
226
-
227
- // If multiple generated positions map to same source, return the first
228
- return positions[0];
229
- }
230
-
231
- /**
232
- * Look up generated position for a given source position
233
- * @param {number} src_line - 1-based line number in source
234
- * @param {number} src_column - 0-based column number in source
235
- * @param {CodeToGeneratedMap} src_to_gen_map - Lookup map
236
- * @returns {CodePosition} Generated position
237
- */
238
- export function get_generated_position(src_line, src_column, src_to_gen_map) {
239
- const maybe_position = maybe_get_generated_position(src_line, src_column, src_to_gen_map);
240
-
241
- if (maybe_position instanceof Error) {
242
- // No mapping found in source map - this shouldn't happen since all tokens should have mappings
243
- throw maybe_position;
244
- }
245
-
246
- return maybe_position;
247
- }
248
-
249
- /**
250
- * Convert line/column to byte offset
251
- * @param {number} line
252
- * @param {number} column
253
- * @param {number[]} line_offsets
254
- * @returns {number}
255
- */
256
- export function loc_to_offset(line, column, line_offsets) {
257
- if (line < 1 || line > line_offsets.length) {
258
- throw new Error(
259
- `Location line or line offsets length is out of bounds, line: ${line}, line offsets length: ${line_offsets.length}`,
260
- );
261
- }
262
- return line_offsets[line - 1] + column;
263
- }
264
-
265
- /**
266
- * Converts line/column positions to byte offsets
267
- * @param {string} text
268
- * @returns {number[]}
269
- */
270
- export function build_line_offsets(text) {
271
- const offsets = [0]; // Line 1 starts at offset 0
272
- for (let i = 0; i < text.length; i++) {
273
- if (text[i] === '\n') {
274
- offsets.push(i + 1);
275
- }
276
- }
277
- return offsets;
278
- }
279
-
280
- /**
281
- * @param {AST.Node | AST.NodeWithLocation} node
282
- * @param {CodeToGeneratedMap} src_to_gen_map
283
- * @param {number[]} gen_line_offsets
284
- * @param {Partial<VolarCodeMapping['data']>} [filtered_data]
285
- * @param {number} [src_max_len]
286
- * @param {number} [gen_max_len]
287
- * @returns {CodeMapping | Error}
288
- */
289
- function maybe_get_mapping_from_node(
290
- node,
291
- src_to_gen_map,
292
- gen_line_offsets,
293
- filtered_data,
294
- src_max_len,
295
- gen_max_len,
296
- ) {
297
- const src_start_offset = /** @type {number} */ (node.start);
298
- const src_end_offset = /** @type {number} */ (node.end);
299
- const src_length = src_max_len || src_end_offset - src_start_offset;
300
- const loc = /** @type {AST.SourceLocation} */ (node.loc);
301
-
302
- const gen_loc = maybe_get_generated_position(loc.start.line, loc.start.column, src_to_gen_map);
303
- if (gen_loc instanceof Error) {
304
- return gen_loc;
305
- }
306
- const gen_start_offset = loc_to_offset(gen_loc.line, gen_loc.column, gen_line_offsets);
307
-
308
- const gen_end_loc = maybe_get_generated_position(loc.end.line, loc.end.column, src_to_gen_map);
309
- if (gen_end_loc instanceof Error) {
310
- return gen_end_loc;
311
- }
312
- const gen_end_offset = loc_to_offset(gen_end_loc.line, gen_end_loc.column, gen_line_offsets);
313
-
314
- const gen_length = gen_max_len || gen_end_offset - gen_start_offset;
315
- return {
316
- sourceOffsets: [src_start_offset],
317
- lengths: [src_length],
318
- generatedOffsets: [gen_start_offset],
319
- generatedLengths: [gen_length],
320
- data: {
321
- ...(filtered_data || mapping_data),
322
- customData: {},
323
- },
324
- };
325
- }
326
-
327
- /**
328
- * @param {AST.Node | AST.NodeWithLocation} node
329
- * @param {CodeToGeneratedMap} src_to_gen_map
330
- * @param {number[]} gen_line_offsets
331
- * @param {Partial<VolarCodeMapping['data']>} [filtered_data]
332
- * @param {number} [src_max_len]
333
- * @param {number} [gen_max_len]
334
- * @returns {CodeMapping}
335
- */
336
- export function get_mapping_from_node(
337
- node,
338
- src_to_gen_map,
339
- gen_line_offsets,
340
- filtered_data,
341
- src_max_len,
342
- gen_max_len,
343
- ) {
344
- const mapping = maybe_get_mapping_from_node(
345
- node,
346
- src_to_gen_map,
347
- gen_line_offsets,
348
- filtered_data,
349
- src_max_len,
350
- gen_max_len,
351
- );
352
-
353
- if (mapping instanceof Error) {
354
- throw mapping;
355
- }
356
-
357
- return mapping;
358
- }
@@ -1,11 +0,0 @@
1
- // Re-export acorn types with Ripple augmentations applied.
2
- // Since this file lives inside the ripple package, TypeScript resolves
3
- // '@types/acorn' from ripple's node_modules. Consumers can import from
4
- // 'ripple/types/acorn' to get the full augmented types without needing
5
- // @types/acorn in their own package.json.
6
- //
7
- // The relative import of './parser' loads the augmentation declarations
8
- // (declare module 'acorn' { ... }) so the re-exported types include
9
- // Ripple-specific nodes like Component, Element, etc.
10
- import './parser.d.ts';
11
- export * from 'acorn';
@@ -1,11 +0,0 @@
1
- // Re-export estree-jsx types with Ripple augmentations applied.
2
- // Since this file lives inside the ripple package, TypeScript resolves
3
- // '@types/estree-jsx' from ripple's node_modules. Consumers can import from
4
- // 'ripple/types/estree-jsx' to get the full augmented types without needing
5
- // @types/estree-jsx in their own package.json.
6
- //
7
- // The relative import of './index' loads the augmentation declarations
8
- // (declare module 'estree-jsx' { ... }) so the re-exported types include
9
- // Ripple-specific extensions like JSXAttribute.shorthand, etc.
10
- import './index';
11
- export * from 'estree-jsx';
@@ -1,11 +0,0 @@
1
- // Re-export estree types with Ripple augmentations applied.
2
- // Since this file lives inside the ripple package, TypeScript resolves
3
- // '@types/estree' from ripple's node_modules. Consumers can import from
4
- // 'ripple/types/estree' to get the full augmented types without needing
5
- // @types/estree in their own package.json.
6
- //
7
- // The relative import of './index' loads the augmentation declarations
8
- // (declare module 'estree' { ... }) so the re-exported types include
9
- // Ripple-specific nodes like Component, Element, etc.
10
- import './index';
11
- export * from 'estree';