rip-lang 3.15.4 → 3.16.1

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 (112) hide show
  1. package/README.md +6 -4
  2. package/bin/rip +167 -12
  3. package/docs/AGENTS.md +1 -1
  4. package/docs/RIP-APP.md +808 -0
  5. package/docs/RIP-DUCKDB.md +477 -0
  6. package/docs/RIP-INTRO.md +396 -0
  7. package/docs/RIP-LANG.md +59 -5
  8. package/docs/RIP-SCHEMA.md +191 -8
  9. package/docs/RIP-TYPES.md +74 -103
  10. package/docs/demo/README.md +4 -3
  11. package/docs/dist/rip.js +3627 -1470
  12. package/docs/dist/rip.min.js +671 -244
  13. package/docs/dist/rip.min.js.br +0 -0
  14. package/docs/example/index.json +7 -7
  15. package/docs/example/index.json.br +0 -0
  16. package/docs/extensions/duckdb/manifest.json +1 -1
  17. package/docs/extensions/duckdb/v1.5.2/linux_amd64/ripdb.duckdb_extension.gz +0 -0
  18. package/docs/extensions/duckdb/v1.5.2/osx_arm64/ripdb.duckdb_extension.gz +0 -0
  19. package/docs/extensions/vscode/print/index.html +2 -1
  20. package/docs/extensions/vscode/print/print-1.0.13.vsix +0 -0
  21. package/docs/extensions/vscode/print/print-1.0.14.vsix +0 -0
  22. package/docs/extensions/vscode/print/print-latest.vsix +0 -0
  23. package/docs/extensions/vscode/rip/rip-0.5.15.vsix +0 -0
  24. package/docs/extensions/vscode/rip/rip-latest.vsix +0 -0
  25. package/docs/ui/bundle.json +61 -0
  26. package/docs/ui/bundle.json.br +0 -0
  27. package/docs/ui/hljs-rip.js +0 -7
  28. package/docs/ui/index.css +66 -23
  29. package/docs/ui/index.html +6 -6
  30. package/package.json +9 -3
  31. package/rip-loader.js +64 -2
  32. package/src/AGENTS.md +63 -36
  33. package/src/browser.js +96 -14
  34. package/src/compiler.js +960 -143
  35. package/src/components.js +794 -88
  36. package/src/{types-emit.js → dts.js} +181 -71
  37. package/src/grammar/README.md +1 -1
  38. package/src/grammar/grammar.rip +111 -97
  39. package/src/lexer.js +132 -18
  40. package/src/parser.js +203 -205
  41. package/src/repl.js +74 -6
  42. package/src/schema/runtime-orm.js +168 -4
  43. package/src/schema/runtime-validate.js +146 -2
  44. package/src/schema/runtime.generated.js +314 -6
  45. package/src/schema/schema.js +5 -5
  46. package/src/sourcemaps.js +277 -1
  47. package/src/stdlib.js +253 -0
  48. package/src/typecheck.js +2023 -106
  49. package/src/types.js +127 -7
  50. package/docs/ui/accordion.rip +0 -103
  51. package/docs/ui/alert-dialog.rip +0 -53
  52. package/docs/ui/autocomplete.rip +0 -115
  53. package/docs/ui/avatar.rip +0 -37
  54. package/docs/ui/badge.rip +0 -15
  55. package/docs/ui/breadcrumb.rip +0 -47
  56. package/docs/ui/button-group.rip +0 -26
  57. package/docs/ui/button.rip +0 -23
  58. package/docs/ui/card.rip +0 -25
  59. package/docs/ui/carousel.rip +0 -110
  60. package/docs/ui/checkbox-group.rip +0 -61
  61. package/docs/ui/checkbox.rip +0 -33
  62. package/docs/ui/collapsible.rip +0 -50
  63. package/docs/ui/combobox.rip +0 -130
  64. package/docs/ui/context-menu.rip +0 -88
  65. package/docs/ui/date-picker.rip +0 -206
  66. package/docs/ui/dialog.rip +0 -60
  67. package/docs/ui/drawer.rip +0 -58
  68. package/docs/ui/editable-value.rip +0 -82
  69. package/docs/ui/field.rip +0 -53
  70. package/docs/ui/fieldset.rip +0 -22
  71. package/docs/ui/form.rip +0 -39
  72. package/docs/ui/grid.rip +0 -901
  73. package/docs/ui/input-group.rip +0 -28
  74. package/docs/ui/input.rip +0 -36
  75. package/docs/ui/label.rip +0 -16
  76. package/docs/ui/menu.rip +0 -134
  77. package/docs/ui/menubar.rip +0 -151
  78. package/docs/ui/meter.rip +0 -36
  79. package/docs/ui/multi-select.rip +0 -203
  80. package/docs/ui/native-select.rip +0 -33
  81. package/docs/ui/nav-menu.rip +0 -126
  82. package/docs/ui/number-field.rip +0 -162
  83. package/docs/ui/otp-field.rip +0 -89
  84. package/docs/ui/pagination.rip +0 -123
  85. package/docs/ui/popover.rip +0 -93
  86. package/docs/ui/preview-card.rip +0 -75
  87. package/docs/ui/progress.rip +0 -25
  88. package/docs/ui/radio-group.rip +0 -57
  89. package/docs/ui/resizable.rip +0 -123
  90. package/docs/ui/scroll-area.rip +0 -145
  91. package/docs/ui/select.rip +0 -151
  92. package/docs/ui/separator.rip +0 -17
  93. package/docs/ui/skeleton.rip +0 -22
  94. package/docs/ui/slider.rip +0 -165
  95. package/docs/ui/spinner.rip +0 -17
  96. package/docs/ui/table.rip +0 -27
  97. package/docs/ui/tabs.rip +0 -113
  98. package/docs/ui/textarea.rip +0 -48
  99. package/docs/ui/toast.rip +0 -87
  100. package/docs/ui/toggle-group.rip +0 -71
  101. package/docs/ui/toggle.rip +0 -24
  102. package/docs/ui/toolbar.rip +0 -38
  103. package/docs/ui/tooltip.rip +0 -85
  104. package/src/app.rip +0 -1571
  105. package/src/sourcemap-merge.js +0 -287
  106. /package/docs/demo/{components → routes}/_layout.rip +0 -0
  107. /package/docs/demo/{components → routes}/about.rip +0 -0
  108. /package/docs/demo/{components → routes}/card.rip +0 -0
  109. /package/docs/demo/{components → routes}/counter.rip +0 -0
  110. /package/docs/demo/{components → routes}/index.rip +0 -0
  111. /package/docs/demo/{components → routes}/todos.rip +0 -0
  112. /package/src/schema/{dts-emit.js → dts.js} +0 -0
@@ -1,287 +0,0 @@
1
- // Source Map V3 — multi-chunk merger.
2
- //
3
- // Concatenates N JS chunks (each with its own inline source map) into one
4
- // JS string + one merged source map. Used by `processRipScripts` to produce
5
- // a single eval'd chunk that DevTools can map back to multiple original
6
- // `.rip` files.
7
- //
8
- // Why this exists: DevTools only honours the LAST `//# sourceMappingURL`
9
- // inside one eval'd chunk. So when N chunks share lexical scope (concat
10
- // + single eval, the bundle-no-router execution model), we must produce
11
- // ONE map that covers all N sources. Source Map V3 supports this natively
12
- // via a multi-entry `sources` / `sourcesContent` array and source-index
13
- // fields in the VLQ mappings — every production JS bundler does this.
14
- //
15
- // Algorithm:
16
- // 1. Strip per-chunk `//# sourceMappingURL=` pragmas from each chunk's JS
17
- // 2. Decode each chunk's `mappings` to absolute coordinates
18
- // 3. Concatenate JS with `\n;\n` separators (statement-safe, +2 newlines
19
- // between chunks)
20
- // 4. Offset each chunk's generated line numbers by the cumulative line
21
- // count of preceding chunks + separators
22
- // 5. Dedupe `sources`, `sourcesContent`, `names` into merged arrays;
23
- // remap each chunk's source-index / name-index fields
24
- // 6. Re-encode as relative VLQ across the full concatenated mapping
25
- //
26
- // Returns { js, mapJSON } where mapJSON is a JSON string ready to embed
27
- // as a base64 data URL via a single `//# sourceMappingURL=` at the end.
28
-
29
- import { vlqEncode, vlqDecode } from './sourcemaps.js';
30
-
31
- // `\n;\n` is statement-safe between chunks (the `;` ensures the previous
32
- // line's expression is terminated). Counts as 2 newlines for line-offset.
33
- const SEPARATOR = '\n;\n';
34
- const SEPARATOR_LINES = 2;
35
-
36
- // Strip a trailing `//# sourceMappingURL=...` pragma from a JS string so
37
- // concatenated chunks don't carry stray maps that DevTools would honor
38
- // in unexpected order. Returns { js, mapJSON } where mapJSON is the
39
- // JSON string extracted from the inline data URL (or null if no pragma).
40
- function extractMap(js) {
41
- const re = /\n?\/\/# sourceMappingURL=data:application\/json(?:;charset=[^;,]+)?;base64,([A-Za-z0-9+/=]+)\s*$/;
42
- const m = js.match(re);
43
- if (!m) return { js, mapJSON: null };
44
- let mapJSON;
45
- try {
46
- // UTF-8-safe decode (counterpart of the encode in compiler.js).
47
- const bin = atob(m[1]);
48
- const bytes = new Uint8Array(bin.length);
49
- for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
50
- mapJSON = new TextDecoder().decode(bytes);
51
- } catch {
52
- return { js: js.slice(0, m.index), mapJSON: null };
53
- }
54
- return { js: js.slice(0, m.index), mapJSON };
55
- }
56
-
57
- // Count the number of newline characters in a string. Used for line-offset
58
- // math when concatenating chunks; one chunk's line count = newline count
59
- // (a chunk starting at line offset L and containing N newlines occupies
60
- // generated lines [L, L+N], so the next chunk starts at L+N+1 if the
61
- // chunk had a trailing newline, or L+N if not — handled via SEPARATOR).
62
- function countNewlines(str) {
63
- let n = 0;
64
- for (let i = 0; i < str.length; i++) if (str.charCodeAt(i) === 10) n++;
65
- return n;
66
- }
67
-
68
- // Decode a Source Map V3 `mappings` field into an array of arrays of
69
- // absolute-coordinate segments. Each segment is one of:
70
- // { genCol } — unmapped (1 field)
71
- // { genCol, src, origLine, origCol } — mapped (4 fields)
72
- // { genCol, src, origLine, origCol, name } — mapped + name (5 fields)
73
- // State: genCol resets to 0 at each line; src/origLine/origCol/name
74
- // persist across lines per the V3 spec.
75
- function decodeMappings(mappingsStr) {
76
- const lines = mappingsStr.split(';');
77
- const result = [];
78
- let src = 0, origLine = 0, origCol = 0, nameIdx = 0;
79
- for (const line of lines) {
80
- const segs = [];
81
- let genCol = 0;
82
- if (line.length > 0) {
83
- for (const segStr of line.split(',')) {
84
- if (segStr.length === 0) continue;
85
- const fields = vlqDecode(segStr);
86
- genCol += fields[0];
87
- if (fields.length === 1) {
88
- segs.push({ genCol });
89
- } else {
90
- src += fields[1];
91
- origLine += fields[2];
92
- origCol += fields[3];
93
- const seg = { genCol, src, origLine, origCol };
94
- if (fields.length >= 5) {
95
- nameIdx += fields[4];
96
- seg.name = nameIdx;
97
- }
98
- segs.push(seg);
99
- }
100
- }
101
- }
102
- result.push(segs);
103
- }
104
- return result;
105
- }
106
-
107
- // Re-encode an array of arrays of absolute-coordinate segments back to
108
- // V3 `mappings` string. Counterpart of decodeMappings.
109
- function encodeMappings(perLineSegs) {
110
- let prevGenCol = 0; // resets per line
111
- let prevSrc = 0, prevOrigLine = 0, prevOrigCol = 0, prevNameIdx = 0;
112
- const out = [];
113
- for (const segs of perLineSegs) {
114
- prevGenCol = 0;
115
- const lineParts = [];
116
- for (const seg of segs) {
117
- if (seg.src == null) {
118
- lineParts.push(vlqEncode(seg.genCol - prevGenCol));
119
- } else {
120
- let s = vlqEncode(seg.genCol - prevGenCol);
121
- s += vlqEncode(seg.src - prevSrc);
122
- s += vlqEncode(seg.origLine - prevOrigLine);
123
- s += vlqEncode(seg.origCol - prevOrigCol);
124
- if (seg.name != null) {
125
- s += vlqEncode(seg.name - prevNameIdx);
126
- prevNameIdx = seg.name;
127
- }
128
- prevSrc = seg.src;
129
- prevOrigLine = seg.origLine;
130
- prevOrigCol = seg.origCol;
131
- lineParts.push(s);
132
- }
133
- prevGenCol = seg.genCol;
134
- }
135
- out.push(lineParts.join(','));
136
- }
137
- return out.join(';');
138
- }
139
-
140
- // Given an array of `{js, mapJSON}` chunks (where mapJSON is the source-map
141
- // V3 JSON string for that chunk, or null/undefined if the chunk has no
142
- // map), produce a single merged result.
143
- //
144
- // Returns:
145
- // {
146
- // js, // concatenated JS, with all per-chunk sourceMappingURL
147
- // // pragmas stripped — caller appends ONE merged pragma
148
- // mapJSON, // V3 source-map JSON string covering all chunks, or
149
- // // null if no chunk had a map
150
- // }
151
- //
152
- // The chunks must be in the order they should be eval'd. Each chunk's JS
153
- // is treated as opaque — we don't parse it, we only count newlines for
154
- // line-offset math.
155
- export function mergeChunks(chunks) {
156
- // Strip per-chunk pragmas first; we'll append exactly one at the end.
157
- const stripped = chunks.map((c) => {
158
- if (c.mapJSON !== undefined) return { js: c.js, mapJSON: c.mapJSON };
159
- return extractMap(c.js);
160
- });
161
-
162
- // If no chunk has a map, the merged JS is just concatenated; no map.
163
- const anyMap = stripped.some((c) => c.mapJSON);
164
- const mergedJS = stripped.map((c) => c.js).join(SEPARATOR);
165
- if (!anyMap) return { js: mergedJS, mapJSON: null };
166
-
167
- // Build merged sources / sourcesContent / names with deduplication
168
- // by string identity. Per-chunk remap tables let us rewrite each
169
- // chunk's source-index / name-index fields into the merged arrays.
170
- const mergedSources = [];
171
- const mergedSourcesContent = [];
172
- const sourceIndexByName = new Map();
173
- const mergedNames = [];
174
- const nameIndexByName = new Map();
175
-
176
- function addSource(name, content) {
177
- if (sourceIndexByName.has(name)) return sourceIndexByName.get(name);
178
- const idx = mergedSources.length;
179
- mergedSources.push(name);
180
- mergedSourcesContent.push(content ?? null);
181
- sourceIndexByName.set(name, idx);
182
- return idx;
183
- }
184
- function addName(name) {
185
- if (nameIndexByName.has(name)) return nameIndexByName.get(name);
186
- const idx = mergedNames.length;
187
- mergedNames.push(name);
188
- nameIndexByName.set(name, idx);
189
- return idx;
190
- }
191
-
192
- // Per-chunk: line offset (cumulative gen-line shift), source-index
193
- // remap, name-index remap, decoded segments.
194
- const chunkInfos = [];
195
- let lineOffset = 0;
196
- for (let i = 0; i < stripped.length; i++) {
197
- const c = stripped[i];
198
- const info = { lineOffset, srcRemap: [], nameRemap: [], perLineSegs: null };
199
-
200
- if (c.mapJSON) {
201
- let map;
202
- try { map = JSON.parse(c.mapJSON); }
203
- catch { map = null; }
204
- if (map && typeof map.mappings === 'string') {
205
- const sources = map.sources || [];
206
- const sourcesContent = map.sourcesContent || [];
207
- info.srcRemap = sources.map((s, idx) => addSource(s, sourcesContent[idx]));
208
- const names = map.names || [];
209
- info.nameRemap = names.map((n) => addName(n));
210
- info.perLineSegs = decodeMappings(map.mappings);
211
- }
212
- }
213
-
214
- chunkInfos.push(info);
215
-
216
- // Advance lineOffset by this chunk's line count + separator (except
217
- // after the last chunk). Use the JS string we'll actually emit so
218
- // line counts stay consistent with the merged output.
219
- const chunkLines = countNewlines(c.js);
220
- const sepLines = (i < stripped.length - 1) ? SEPARATOR_LINES : 0;
221
- lineOffset += chunkLines + sepLines;
222
- }
223
-
224
- // Walk all chunks and emit their segments into the merged per-line
225
- // segment array, with each chunk's gen-line indices shifted by the
226
- // chunk's lineOffset and source/name indices remapped.
227
- const totalLines = lineOffset + 1; // last chunk's lines fit within
228
- const mergedPerLineSegs = new Array(totalLines).fill(null).map(() => []);
229
-
230
- for (const info of chunkInfos) {
231
- if (!info.perLineSegs) continue;
232
- for (let li = 0; li < info.perLineSegs.length; li++) {
233
- const target = info.lineOffset + li;
234
- if (target >= mergedPerLineSegs.length) {
235
- // Defensive: extend if a chunk has more lines than we counted.
236
- while (mergedPerLineSegs.length <= target) mergedPerLineSegs.push([]);
237
- }
238
- for (const seg of info.perLineSegs[li]) {
239
- if (seg.src == null) {
240
- mergedPerLineSegs[target].push({ genCol: seg.genCol });
241
- } else {
242
- const remapped = {
243
- genCol: seg.genCol,
244
- src: info.srcRemap[seg.src],
245
- origLine: seg.origLine,
246
- origCol: seg.origCol,
247
- };
248
- if (seg.name != null) remapped.name = info.nameRemap[seg.name];
249
- mergedPerLineSegs[target].push(remapped);
250
- }
251
- }
252
- }
253
- }
254
-
255
- const mergedMappings = encodeMappings(mergedPerLineSegs);
256
- const mergedMap = {
257
- version: 3,
258
- sources: mergedSources,
259
- sourcesContent: mergedSourcesContent,
260
- names: mergedNames,
261
- mappings: mergedMappings,
262
- };
263
- return { js: mergedJS, mapJSON: JSON.stringify(mergedMap) };
264
- }
265
-
266
- // UTF-8-safe base64 encode for embedding mapJSON as a data URL pragma.
267
- // Counterpart of the encode used in src/compiler.js.
268
- function utf8ToBase64(str) {
269
- if (typeof Buffer !== 'undefined') {
270
- return Buffer.from(str, 'utf8').toString('base64');
271
- }
272
- // Browser path: TextEncoder + btoa over latin1 bytes.
273
- const bytes = new TextEncoder().encode(str);
274
- let bin = '';
275
- for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);
276
- return btoa(bin);
277
- }
278
-
279
- // Convenience: take chunks, run mergeChunks, append a single
280
- // `//# sourceMappingURL=` data-URL pragma to the merged JS, return it.
281
- // If no chunk had a map, returns the concat'd JS unchanged.
282
- export function mergeChunksWithInlineMap(chunks) {
283
- const { js, mapJSON } = mergeChunks(chunks);
284
- if (!mapJSON) return js;
285
- const b64 = utf8ToBase64(mapJSON);
286
- return js + '\n//# sourceMappingURL=data:application/json;base64,' + b64 + '\n';
287
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes