rip-lang 3.15.2 → 3.15.3

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.
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rip-lang",
3
- "version": "3.15.2",
3
+ "version": "3.15.3",
4
4
  "description": "A modern language that compiles to JavaScript",
5
5
  "type": "module",
6
6
  "main": "src/compiler.js",
package/src/browser.js CHANGED
@@ -222,14 +222,22 @@ async function processRipScripts() {
222
222
  }
223
223
  expanded.push(...individual);
224
224
 
225
- // Source maps are ON by default `data-debug="false"` opts out.
226
- // Individually compile each source with its own source map; we'll
227
- // sequentially eval them per-component so each has a self-consistent
228
- // map (DevTools only honours the last sourceMappingURL inside an
229
- // eval, so concatenating maps doesn't work).
225
+ // Bundle / multi-source path. Components defined in one .rip file
226
+ // need to be visible to siblings (e.g. `WidgetGallery` referencing
227
+ // sibling widgets like `Toast`, `Dialog`, `Menu`). To make that
228
+ // work we concatenate every compiled chunk into ONE async-IIFE and
229
+ // eval it as a single closure — declarations made by one source
230
+ // are visible to all subsequent sources via lexical scope.
231
+ //
232
+ // Trade-off: source maps don't work in concat mode (each
233
+ // `compileToJS` call emits its own map; concatenation would need a
234
+ // map merger we don't have). Source maps still work for:
235
+ // - the data-router path (app.launch component compile, Phase 2)
236
+ // - the single-inline-script path (one source = one map)
237
+ // The bundle no-router path is mostly used by component libraries
238
+ // (packages/ui itself) where step-debugging is less critical.
239
+ // Inline source maps are skipped here unconditionally.
230
240
  const debug = runtimeTag?.getAttribute('data-debug') !== 'false';
231
- // Update the global flag so app.launch()'s compile path (in app.rip)
232
- // sees the same setting as our local `debug` variable.
233
241
  if (globalThis.__ripDebug) globalThis.__ripDebug.enabled = debug;
234
242
  const baseOpts = { skipRuntimes: true, skipExports: true, skipImports: true };
235
243
  const compiled = [];
@@ -237,11 +245,8 @@ async function processRipScripts() {
237
245
  for (const s of expanded) {
238
246
  if (!s.code) continue;
239
247
  const ripName = s.url || `inline-${++inlineCounter}.rip`;
240
- const opts = debug
241
- ? { ...baseOpts, sourceMap: 'inline', filename: ripName }
242
- : baseOpts;
243
248
  try {
244
- const js = compileToJS(s.code, opts);
249
+ const js = compileToJS(s.code, baseOpts);
245
250
  compiled.push({ js, url: ripName });
246
251
  } catch (e) {
247
252
  console.error(_formatError(e, { source: s.code, file: ripName, color: false }));
@@ -269,35 +274,26 @@ async function processRipScripts() {
269
274
  }
270
275
  }
271
276
 
272
- // Execute compiled code per-component so each has its own valid
273
- // source map (DevTools only honours the last `sourceMappingURL`
274
- // pragma inside one evaluated chunk, so concatenating multiple
275
- // source-mapped chunks would lose all but the last). Components
276
- // share scope via globalThis attachment typical Rip definitions
277
- // (`Foo = component`, `Bar = ...`) compile to globalThis-attached
278
- // bindings under `skipExports/skipImports`, which survive between
279
- // the per-component evals.
277
+ // Concatenate all compiled chunks into one async IIFE so component
278
+ // declarations made in earlier chunks are visible (via lexical
279
+ // scope) to later chunks AND to the final mount step. Without
280
+ // this, each chunk's `let Foo = class ...` dies when its IIFE
281
+ // returns and `WidgetGallery` (defined in one chunk) can't see
282
+ // `Toast` (defined in another).
280
283
  if (compiled.length > 0) {
281
- let anyError = false;
282
- for (const c of compiled) {
283
- try {
284
- await (0, eval)(debug ? wrapForEval(c.js, c.url) : `(async()=>{\n${c.js}\n})()`);
285
- } catch (e) {
286
- anyError = true;
287
- if (e instanceof SyntaxError) console.error(`Rip syntax error in ${c.url}: ${e.message}`);
288
- else console.error(`Rip runtime error in ${c.url}:`, e);
289
- }
290
- }
291
-
292
- // Final mount step — runs after all components are defined.
293
284
  const mount = runtimeTag?.getAttribute('data-mount');
294
- if (mount) {
295
- const target = runtimeTag.getAttribute('data-target') || 'body';
296
- try { await (0, eval)(`(async()=>{ ${mount}.mount(${JSON.stringify(target)}); })()`); }
297
- catch (e) { console.error(`Rip mount error (${mount}):`, e); }
285
+ const target = runtimeTag?.getAttribute('data-target') || 'body';
286
+ const mountSnippet = mount ? `\n${mount}.mount(${JSON.stringify(target)});\n` : '';
287
+ const merged = compiled.map(c => c.js).join('\n;\n');
288
+ let ok = true;
289
+ try {
290
+ await (0, eval)(`(async()=>{\n${merged}${mountSnippet}\n})()`);
291
+ } catch (e) {
292
+ ok = false;
293
+ if (e instanceof SyntaxError) console.error(`Rip syntax error: ${e.message}`);
294
+ else console.error('Rip runtime error:', e);
298
295
  }
299
-
300
- if (!anyError) document.body.classList.add('ready');
296
+ if (ok) document.body.classList.add('ready');
301
297
  }
302
298
  }
303
299
  }