ripple 0.2.67 → 0.2.68

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Ripple is an elegant TypeScript UI framework",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.2.67",
6
+ "version": "0.2.68",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index.js",
9
9
  "main": "src/runtime/index.js",
@@ -87,6 +87,10 @@ const visitors = {
87
87
  next(scope !== undefined && scope !== state.scope ? { ...state, scope } : state);
88
88
  },
89
89
 
90
+ Program(_, context) {
91
+ return context.next({ ...context.state, function_depth: 0, expression: null });
92
+ },
93
+
90
94
  Identifier(node, context) {
91
95
  const binding = context.state.scope.get(node.name);
92
96
  const parent = context.path.at(-1);
@@ -133,6 +137,25 @@ const visitors = {
133
137
  },
134
138
 
135
139
  CallExpression(node, context) {
140
+ const callee = node.callee;
141
+
142
+ if (
143
+ context.state.function_depth === 0 &&
144
+ ((callee.type === 'Identifier' && callee.name === 'track') ||
145
+ (callee.type === 'MemberExpression' &&
146
+ callee.object.type === 'Identifier' &&
147
+ callee.property.type === 'Identifier' &&
148
+ callee.property.name === 'track' &&
149
+ !callee.computed)) &&
150
+ is_ripple_import(callee, context)
151
+ ) {
152
+ error(
153
+ '`track` can only be used within a reactive context, such as a component, function or class that is used or created from a component',
154
+ context.state.analysis.module.filename,
155
+ node,
156
+ );
157
+ }
158
+
136
159
  if (context.state.metadata?.tracking === false) {
137
160
  context.state.metadata.tracking = true;
138
161
  }
@@ -145,27 +168,20 @@ const visitors = {
145
168
  },
146
169
 
147
170
  VariableDeclaration(node, context) {
148
- const { state, visit, path } = context;
171
+ const { state, visit } = context;
149
172
 
150
173
  for (const declarator of node.declarations) {
151
174
  if (is_inside_component(context) && node.kind === 'var') {
152
175
  error(
153
- 'var declarations are not allowed in components, use let or const instead',
176
+ '`var` declarations are not allowed in components, use let or const instead',
154
177
  state.analysis.module.filename,
155
178
  declarator,
156
179
  );
157
180
  }
158
181
  const metadata = { tracking: false, await: false };
159
- const parent = path.at(-1);
160
- const init_is_untracked =
161
- declarator.init !== null &&
162
- declarator.init.type === 'CallExpression' &&
163
- is_ripple_import(declarator.init.callee, context) &&
164
- declarator.init.callee.type === 'Identifier' &&
165
- (declarator.init.callee.name === 'untrack' || declarator.init.callee.name === 'deferred');
166
182
 
167
183
  if (declarator.id.type === 'Identifier') {
168
- visit(declarator, state);
184
+ visit(declarator, state);
169
185
  } else {
170
186
  const paths = extract_paths(declarator.id);
171
187
 
@@ -234,7 +250,7 @@ const visitors = {
234
250
  }
235
251
  const elements = [];
236
252
 
237
- context.next({ ...context.state, elements });
253
+ context.next({ ...context.state, elements, function_depth: context.state.function_depth + 1 });
238
254
 
239
255
  const css = node.css;
240
256
 
@@ -29,8 +29,8 @@ import { is_event_attribute, is_passive_event } from '../../../utils/events.js';
29
29
 
30
30
  function add_ripple_internal_import(context) {
31
31
  if (!context.state.to_ts) {
32
- if (!context.state.imports.has(`import * as $ from 'ripple/internal/client'`)) {
33
- context.state.imports.add(`import * as $ from 'ripple/internal/client'`);
32
+ if (!context.state.imports.has(`import * as _$_ from 'ripple/internal/client'`)) {
33
+ context.state.imports.add(`import * as _$_ from 'ripple/internal/client'`);
34
34
  }
35
35
  }
36
36
  }
@@ -66,7 +66,7 @@ function visit_function(node, context) {
66
66
 
67
67
  if (!is_inside_component(context, true) && is_component_level_function(context)) {
68
68
  add_ripple_internal_import(context);
69
- new_body.push(b.var('__block', b.call('$.scope')));
69
+ new_body.push(b.var('__block', b.call('_$_.scope')));
70
70
  }
71
71
  if (body.type === 'BlockStatement') {
72
72
  new_body.push(...body.body);
@@ -135,7 +135,7 @@ const visitors = {
135
135
  context.state.metadata.tracking = true;
136
136
  }
137
137
  if (node.tracked) {
138
- return b.call('$.get', build_getter(node, context));
138
+ return b.call('_$_.get', build_getter(node, context));
139
139
  }
140
140
  }
141
141
 
@@ -167,8 +167,12 @@ const visitors = {
167
167
 
168
168
  if (
169
169
  !context.state.to_ts &&
170
- callee.type === 'Identifier' &&
171
- callee.name === 'track' &&
170
+ ((callee.type === 'Identifier' && callee.name === 'track') ||
171
+ (callee.type === 'MemberExpression' &&
172
+ callee.object.type === 'Identifier' &&
173
+ callee.property.type === 'Identifier' &&
174
+ callee.property.name === 'track' &&
175
+ !callee.computed)) &&
172
176
  is_ripple_import(callee, context)
173
177
  ) {
174
178
  if (node.arguments.length === 0) {
@@ -186,9 +190,6 @@ const visitors = {
186
190
  (parent?.type === 'MemberExpression' && parent.property === node) ||
187
191
  is_inside_call_expression(context) ||
188
192
  !context.path.some((node) => node.type === 'Component') ||
189
- (is_ripple_import(callee, context) &&
190
- (callee.type !== 'Identifier' ||
191
- (callee.name !== 'array' && callee.name !== 'deferred'))) ||
192
193
  is_declared_function_within_component(callee, context)
193
194
  ) {
194
195
  return context.next();
@@ -200,11 +201,11 @@ const visitors = {
200
201
 
201
202
  if (callee.computed) {
202
203
  return b.call(
203
- '$.with_scope',
204
+ '_$_.with_scope',
204
205
  b.id('__block'),
205
206
  b.thunk(
206
207
  b.call(
207
- '$.call_property',
208
+ '_$_.call_property',
208
209
  context.visit(callee.object),
209
210
  context.visit(property),
210
211
  callee.optional ? b.true : undefined,
@@ -217,7 +218,7 @@ const visitors = {
217
218
  }
218
219
 
219
220
  return b.call(
220
- '$.with_scope',
221
+ '_$_.with_scope',
221
222
  b.id('__block'),
222
223
  b.thunk(
223
224
  {
@@ -269,7 +270,7 @@ const visitors = {
269
270
  }
270
271
 
271
272
  return b.call(
272
- '$.with_scope',
273
+ '_$_.with_scope',
273
274
  b.id('__block'),
274
275
  b.thunk({
275
276
  ...node,
@@ -290,7 +291,7 @@ const visitors = {
290
291
  add_ripple_internal_import(context);
291
292
 
292
293
  return b.call(
293
- '$.get_property',
294
+ '_$_.get_property',
294
295
  context.visit(node.object),
295
296
  node.computed ? context.visit(node.property) : b.literal(node.property.name),
296
297
  node.optional ? b.true : undefined,
@@ -351,13 +352,13 @@ const visitors = {
351
352
  // TypeScript mode: lighter transformation
352
353
  if (metadata.tracking && !metadata.await) {
353
354
  expression = b.call(
354
- '$.derived',
355
+ '_$_.derived',
355
356
  b.thunk(context.visit(declarator.init)),
356
357
  b.id('__block'),
357
358
  );
358
359
  } else {
359
360
  expression = b.call(
360
- '$.tracked',
361
+ '_$_.tracked',
361
362
  declarator.init === null ? undefined : context.visit(declarator.init),
362
363
  b.id('__block'),
363
364
  );
@@ -369,9 +370,9 @@ const visitors = {
369
370
  expression = b.call(
370
371
  b.await(
371
372
  b.call(
372
- '$.resume_context',
373
+ '_$_.resume_context',
373
374
  b.call(
374
- '$.async_computed',
375
+ '_$_.async_computed',
375
376
  b.thunk(context.visit(declarator.init), true),
376
377
  b.id('__block'),
377
378
  ),
@@ -380,13 +381,13 @@ const visitors = {
380
381
  );
381
382
  } else if (metadata.tracking && !metadata.await) {
382
383
  expression = b.call(
383
- '$.derived',
384
+ '_$_.derived',
384
385
  b.thunk(context.visit(declarator.init)),
385
386
  b.id('__block'),
386
387
  );
387
388
  } else {
388
389
  expression = b.call(
389
- '$.tracked',
390
+ '_$_.tracked',
390
391
  declarator.init === null ? undefined : context.visit(declarator.init),
391
392
  b.id('__block'),
392
393
  );
@@ -481,9 +482,9 @@ const visitors = {
481
482
  const expression = visit(attr.value, { ...state, metadata });
482
483
 
483
484
  if (name === '$value' || metadata.tracking) {
484
- local_updates.push(b.stmt(b.call('$.set_value', id, expression)));
485
+ local_updates.push(b.stmt(b.call('_$_.set_value', id, expression)));
485
486
  } else {
486
- state.init.push(b.stmt(b.call('$.set_value', id, expression)));
487
+ state.init.push(b.stmt(b.call('_$_.set_value', id, expression)));
487
488
  }
488
489
 
489
490
  continue;
@@ -495,9 +496,9 @@ const visitors = {
495
496
  const expression = visit(attr.value, { ...state, metadata });
496
497
 
497
498
  if (name === '$checked' || metadata.tracking) {
498
- local_updates.push(b.stmt(b.call('$.set_checked', id, expression)));
499
+ local_updates.push(b.stmt(b.call('_$_.set_checked', id, expression)));
499
500
  } else {
500
- state.init.push(b.stmt(b.call('$.set_checked', id, expression)));
501
+ state.init.push(b.stmt(b.call('_$_.set_checked', id, expression)));
501
502
  }
502
503
  continue;
503
504
  }
@@ -508,9 +509,9 @@ const visitors = {
508
509
  const expression = visit(attr.value, { ...state, metadata });
509
510
 
510
511
  if (name === '$selected' || metadata.tracking) {
511
- local_updates.push(b.stmt(b.call('$.set_selected', id, expression)));
512
+ local_updates.push(b.stmt(b.call('_$_.set_selected', id, expression)));
512
513
  } else {
513
- state.init.push(b.stmt(b.call('$.set_selected', id, expression)));
514
+ state.init.push(b.stmt(b.call('_$_.set_selected', id, expression)));
514
515
  }
515
516
  continue;
516
517
  }
@@ -563,7 +564,7 @@ const visitors = {
563
564
  state.init.push(
564
565
  b.stmt(
565
566
  b.call(
566
- '$.event',
567
+ '_$_.event',
567
568
  b.literal(event_name),
568
569
  id,
569
570
  handler,
@@ -588,7 +589,7 @@ const visitors = {
588
589
  local_updates.push(b.stmt(b.assignment('=', b.member(id, attribute), expression)));
589
590
  } else {
590
591
  local_updates.push(
591
- b.stmt(b.call('$.set_attribute', id, b.literal(attribute), expression)),
592
+ b.stmt(b.call('_$_.set_attribute', id, b.literal(attribute), expression)),
592
593
  );
593
594
  }
594
595
  } else {
@@ -597,7 +598,9 @@ const visitors = {
597
598
  if (is_dom_property(name)) {
598
599
  state.init.push(b.stmt(b.assignment('=', b.member(id, name), expression)));
599
600
  } else {
600
- state.init.push(b.stmt(b.call('$.set_attribute', id, b.literal(name), expression)));
601
+ state.init.push(
602
+ b.stmt(b.call('_$_.set_attribute', id, b.literal(name), expression)),
603
+ );
601
604
  }
602
605
  }
603
606
  }
@@ -605,7 +608,7 @@ const visitors = {
605
608
  spread_attributes.push(b.spread(visit(attr.argument, state)));
606
609
  } else if (attr.type === 'RefAttribute') {
607
610
  const id = state.flush_node();
608
- state.init.push(b.stmt(b.call('$.ref', id, b.thunk(visit(attr.argument, state)))));
611
+ state.init.push(b.stmt(b.call('_$_.ref', id, b.thunk(visit(attr.argument, state)))));
609
612
  }
610
613
  }
611
614
 
@@ -626,11 +629,12 @@ const visitors = {
626
629
  if (node.metadata.scoped && state.component.css) {
627
630
  expression = b.binary('+', b.literal(state.component.css.hash + ' '), expression);
628
631
  }
632
+ const is_html = context.state.metadata.namespace === 'html' && node.id.name !== 'svg'
629
633
 
630
- if (class_attribute.name.name === '$class' || metadata.tracking) {
631
- local_updates.push(b.stmt(b.call('$.set_class', id, expression)));
634
+ if (metadata.tracking) {
635
+ local_updates.push(b.stmt(b.call('_$_.set_class', id, expression, is_html)));
632
636
  } else {
633
- state.init.push(b.stmt(b.call('$.set_class', id, expression)));
637
+ state.init.push(b.stmt(b.call('_$_.set_class', id, expression, is_html)));
634
638
  }
635
639
  }
636
640
  } else if (node.metadata.scoped && state.component.css) {
@@ -644,7 +648,7 @@ const visitors = {
644
648
  if (spread_attributes !== null && spread_attributes.length > 0) {
645
649
  const id = state.flush_node();
646
650
  state.init.push(
647
- b.stmt(b.call('$.render_spread', id, b.thunk(b.object(spread_attributes)))),
651
+ b.stmt(b.call('_$_.render_spread', id, b.thunk(b.object(spread_attributes)))),
648
652
  );
649
653
  }
650
654
 
@@ -668,7 +672,7 @@ const visitors = {
668
672
 
669
673
  if (update.length > 0) {
670
674
  if (state.scope.parent.declarations.size > 0) {
671
- state.init.push(b.stmt(b.call('$.render', b.thunk(b.block(update), !!update.async))));
675
+ state.init.push(b.stmt(b.call('_$_.render', b.thunk(b.block(update), !!update.async))));
672
676
  } else {
673
677
  state.update.push(...update);
674
678
  }
@@ -710,7 +714,7 @@ const visitors = {
710
714
  ),
711
715
  );
712
716
  } else if (attr.type === 'RefAttribute') {
713
- props.push(b.prop('init', b.call('$.ref_prop'), visit(attr.argument, state), true));
717
+ props.push(b.prop('init', b.call('_$_.ref_prop'), visit(attr.argument, state), true));
714
718
  } else if (attr.type === 'AccessorAttribute') {
715
719
  let get_expr;
716
720
 
@@ -791,14 +795,14 @@ const visitors = {
791
795
  b.call(
792
796
  node.id,
793
797
  id,
794
- b.call('$.spread_props', b.thunk(b.object(props)), b.id('__block')),
795
- b.id('$.active_block'),
798
+ b.call('_$_.spread_props', b.thunk(b.object(props)), b.id('__block')),
799
+ b.id('_$_.active_block'),
796
800
  ),
797
801
  ),
798
802
  );
799
803
  } else {
800
804
  state.init.push(
801
- b.stmt(b.call(visit(node.id, state), id, b.object(props), b.id('$.active_block'))),
805
+ b.stmt(b.call(visit(node.id, state), id, b.object(props), b.id('_$_.active_block'))),
802
806
  );
803
807
  }
804
808
  }
@@ -821,7 +825,7 @@ const visitors = {
821
825
  [b.id('__anchor'), ...node.params.map((param) => context.visit(param, context.state))],
822
826
  b.block(
823
827
  metadata.await
824
- ? [b.stmt(b.call('$.async', b.thunk(b.block(body_statements), true)))]
828
+ ? [b.stmt(b.call('_$_.async', b.thunk(b.block(body_statements), true)))]
825
829
  : body_statements,
826
830
  ),
827
831
  );
@@ -859,12 +863,12 @@ const visitors = {
859
863
  }
860
864
 
861
865
  const body_statements = [
862
- b.stmt(b.call('$.push_component')),
866
+ b.stmt(b.call('_$_.push_component')),
863
867
  ...transform_body(node.body, {
864
868
  ...context,
865
869
  state: { ...context.state, component: node, metadata },
866
870
  }),
867
- b.stmt(b.call('$.pop_component')),
871
+ b.stmt(b.call('_$_.pop_component')),
868
872
  ];
869
873
 
870
874
  if (node.css !== null && node.css) {
@@ -879,7 +883,7 @@ const visitors = {
879
883
  b.block([
880
884
  ...(prop_statements ?? []),
881
885
  ...(metadata.await
882
- ? [b.stmt(b.call('$.async', b.thunk(b.block(body_statements), true)))]
886
+ ? [b.stmt(b.call('_$_.async', b.thunk(b.block(body_statements), true)))]
883
887
  : body_statements),
884
888
  ]),
885
889
  );
@@ -906,7 +910,7 @@ const visitors = {
906
910
  }
907
911
 
908
912
  return b.call(
909
- '$.set_property',
913
+ '_$_.set_property',
910
914
  context.visit(left.object, { ...context.state, metadata: { tracking: false } }),
911
915
  left.computed ? context.visit(left.property) : b.literal(left.property.name),
912
916
  operator === '='
@@ -926,7 +930,7 @@ const visitors = {
926
930
  const right = node.right;
927
931
 
928
932
  return b.call(
929
- '$.set',
933
+ '_$_.set',
930
934
  context.visit(left, { ...context.state, metadata: { tracking: null } }),
931
935
  operator === '='
932
936
  ? context.visit(right)
@@ -960,7 +964,7 @@ const visitors = {
960
964
  context.state.metadata.tracking = true;
961
965
 
962
966
  return b.call(
963
- node.prefix ? '$.update_pre_property' : '$.update_property',
967
+ node.prefix ? '_$_.update_pre_property' : '_$_.update_property',
964
968
  context.visit(argument.object, { ...context.state, metadata: { tracking: false } }),
965
969
  argument.computed ? context.visit(argument.property) : b.literal(argument.property.name),
966
970
  b.id('__block'),
@@ -970,7 +974,7 @@ const visitors = {
970
974
 
971
975
  if (argument.type === 'Identifier' && argument.tracked) {
972
976
  return b.call(
973
- node.prefix ? '$.update_pre' : '$.update',
977
+ node.prefix ? '_$_.update_pre' : '_$_.update',
974
978
  context.visit(argument, { ...context.state, metadata: { tracking: null } }),
975
979
  b.id('__block'),
976
980
  node.operator === '--' ? b.literal(-1) : undefined,
@@ -1010,7 +1014,7 @@ const visitors = {
1010
1014
  context.state.init.push(
1011
1015
  b.stmt(
1012
1016
  b.call(
1013
- '$.for',
1017
+ '_$_.for',
1014
1018
  id,
1015
1019
  b.thunk(context.visit(node.right)),
1016
1020
  b.arrow(
@@ -1070,7 +1074,7 @@ const visitors = {
1070
1074
  statements.push(
1071
1075
  b.stmt(
1072
1076
  b.call(
1073
- '$.if',
1077
+ '_$_.if',
1074
1078
  id,
1075
1079
  b.arrow(
1076
1080
  [b.id('__render')],
@@ -1119,13 +1123,13 @@ const visitors = {
1119
1123
  });
1120
1124
 
1121
1125
  if (metadata.pending) {
1122
- body = [b.stmt(b.call('$.async', b.thunk(b.block(body), true)))];
1126
+ body = [b.stmt(b.call('_$_.async', b.thunk(b.block(body), true)))];
1123
1127
  }
1124
1128
 
1125
1129
  context.state.init.push(
1126
1130
  b.stmt(
1127
1131
  b.call(
1128
- '$.try',
1132
+ '_$_.try',
1129
1133
  id,
1130
1134
  b.arrow([b.id('__anchor')], b.block(body)),
1131
1135
  node.handler === null
@@ -1151,7 +1155,7 @@ const visitors = {
1151
1155
  context.state.metadata.await = true;
1152
1156
  }
1153
1157
 
1154
- return b.call(b.await(b.call('$.maybe_tracked', context.visit(node.argument))));
1158
+ return b.call(b.await(b.call('_$_.maybe_tracked', context.visit(node.argument))));
1155
1159
  },
1156
1160
 
1157
1161
  BinaryExpression(node, context) {
@@ -1489,7 +1493,7 @@ function transform_children(children, context) {
1489
1493
  const metadata = { await: false };
1490
1494
  state.init.push(visit(node, { ...state, metadata }));
1491
1495
  if (metadata.await) {
1492
- state.init.push(b.if(b.call('$.aborted'), b.return(null)));
1496
+ state.init.push(b.if(b.call('_$_.aborted'), b.return(null)));
1493
1497
  if (state.metadata?.await === false) {
1494
1498
  state.metadata.await = true;
1495
1499
  }
@@ -1508,13 +1512,13 @@ function transform_children(children, context) {
1508
1512
  return cached;
1509
1513
  } else if (current_prev !== null) {
1510
1514
  const id = get_id(node);
1511
- state.setup.push(b.var(id, b.call('$.sibling', current_prev())));
1515
+ state.setup.push(b.var(id, b.call('_$_.sibling', current_prev())));
1512
1516
  cached = id;
1513
1517
  return id;
1514
1518
  } else if (initial !== null) {
1515
1519
  if (is_fragment) {
1516
1520
  const id = get_id(node);
1517
- state.setup.push(b.var(id, b.call('$.child_frag', initial)));
1521
+ state.setup.push(b.var(id, b.call('_$_.child_frag', initial)));
1518
1522
  cached = id;
1519
1523
  return id;
1520
1524
  }
@@ -1525,7 +1529,7 @@ function transform_children(children, context) {
1525
1529
  }
1526
1530
 
1527
1531
  const id = get_id(node);
1528
- state.setup.push(b.var(id, b.call('$.child', state.flush_node())));
1532
+ state.setup.push(b.var(id, b.call('_$_.child', state.flush_node())));
1529
1533
  cached = id;
1530
1534
  return id;
1531
1535
  } else {
@@ -1544,7 +1548,7 @@ function transform_children(children, context) {
1544
1548
  if (metadata.tracking) {
1545
1549
  state.template.push(' ');
1546
1550
  const id = flush_node();
1547
- state.update.push(b.stmt(b.call('$.set_text', id, expression)));
1551
+ state.update.push(b.stmt(b.call('_$_.set_text', id, expression)));
1548
1552
  if (metadata.await) {
1549
1553
  state.update.async = true;
1550
1554
  }
@@ -1556,7 +1560,7 @@ function transform_children(children, context) {
1556
1560
  state.template.push(' ');
1557
1561
  state.init.push(
1558
1562
  b.stmt(
1559
- b.assignment('=', b.member(b.call('$.child', id), b.id('nodeValue')), expression),
1563
+ b.assignment('=', b.member(b.call('_$_.child', id), b.id('nodeValue')), expression),
1560
1564
  ),
1561
1565
  );
1562
1566
  }
@@ -1564,7 +1568,7 @@ function transform_children(children, context) {
1564
1568
  // Handle Text nodes in fragments
1565
1569
  state.template.push(' ');
1566
1570
  const id = flush_node();
1567
- state.update.push(b.stmt(b.call('$.set_text', id, expression)));
1571
+ state.update.push(b.stmt(b.call('_$_.set_text', id, expression)));
1568
1572
  if (metadata.await) {
1569
1573
  state.update.async = true;
1570
1574
  }
@@ -1589,9 +1593,9 @@ function transform_children(children, context) {
1589
1593
 
1590
1594
  if (root && initial !== null && template_id !== null) {
1591
1595
  const flags = is_fragment ? b.literal(TEMPLATE_FRAGMENT) : b.literal(0);
1592
- state.final.push(b.stmt(b.call('$.append', b.id('__anchor'), initial)));
1596
+ state.final.push(b.stmt(b.call('_$_.append', b.id('__anchor'), initial)));
1593
1597
  state.hoisted.push(
1594
- b.var(template_id, b.call('$.template', join_template(state.template), flags)),
1598
+ b.var(template_id, b.call('_$_.template', join_template(state.template), flags)),
1595
1599
  );
1596
1600
  }
1597
1601
  }
@@ -1610,7 +1614,7 @@ function transform_body(body, { visit, state }) {
1610
1614
  transform_children(body, { visit, state: body_state, root: true });
1611
1615
 
1612
1616
  if (body_state.update.length > 0) {
1613
- body_state.init.push(b.stmt(b.call('$.render', b.thunk(b.block(body_state.update)))));
1617
+ body_state.init.push(b.stmt(b.call('_$_.render', b.thunk(b.block(body_state.update)))));
1614
1618
  }
1615
1619
 
1616
1620
  return [...body_state.setup, ...body_state.init, ...body_state.final];
@@ -1646,7 +1650,7 @@ export function transform(filename, source, analysis, to_ts) {
1646
1650
  if (state.events.size > 0) {
1647
1651
  program.body.push(
1648
1652
  b.stmt(
1649
- b.call('$.delegate', b.array(Array.from(state.events).map((name) => b.literal(name)))),
1653
+ b.call('_$_.delegate', b.array(Array.from(state.events).map((name) => b.literal(name)))),
1650
1654
  ),
1651
1655
  );
1652
1656
  }
@@ -262,7 +262,7 @@ export class Scope {
262
262
  * @param {Identifier} node
263
263
  * @param {Binding['kind']} kind
264
264
  * @param {DeclarationKind} declaration_kind
265
- * @param {null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration | AST.EachBlock | AST.SnippetBlock} initial
265
+ * @param {null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration} initial
266
266
  * @returns {Binding}
267
267
  */
268
268
  declare(node, kind, declaration_kind, initial = null) {
@@ -276,9 +276,12 @@ export class Scope {
276
276
  }
277
277
  }
278
278
 
279
+ if (node.name === '_$_') {
280
+ throw new Error('Cannot declare a variable named "_$_" as it is a reserved identifier');
281
+ }
282
+
279
283
  if (this.declarations.has(node.name)) {
280
- // This also errors on var/function types, but that's arguably a good thing
281
- e.declaration_duplicate(node, node.name);
284
+ throw new Error(`'${node.name}' has already been declared in the current scope`);
282
285
  }
283
286
 
284
287
  /** @type {Binding} */
@@ -418,6 +418,18 @@ export function is_ripple_import(callee, context) {
418
418
  if (callee.type === 'Identifier') {
419
419
  const binding = context.state.scope.get(callee.name);
420
420
 
421
+ return (
422
+ binding?.declaration_kind === 'import' &&
423
+ binding.initial.source.type === 'Literal' &&
424
+ binding.initial.source.value === 'ripple'
425
+ );
426
+ } else if (
427
+ callee.type === 'MemberExpression' &&
428
+ callee.object.type === 'Identifier' &&
429
+ !callee.computed
430
+ ) {
431
+ const binding = context.state.scope.get(callee.object.name);
432
+
421
433
  return (
422
434
  binding?.declaration_kind === 'import' &&
423
435
  binding.initial.source.type === 'Literal' &&
package/src/utils/ast.js CHANGED
@@ -101,7 +101,7 @@ function _extract_paths(assignments = [], param, expression, update_expression,
101
101
  }
102
102
  }
103
103
 
104
- return b.call('$.exclude_from_object', expression(object), b.array(props));
104
+ return b.call('_$_.exclude_from_object', expression(object), b.array(props));
105
105
  };
106
106
 
107
107
  if (prop.argument.type === 'Identifier') {
@@ -202,7 +202,7 @@ function _extract_paths(assignments = [], param, expression, update_expression,
202
202
  }
203
203
 
204
204
  export function build_fallback(expression, fallback) {
205
- return b.call('$.fallback', expression, fallback);
205
+ return b.call('_$_.fallback', expression, fallback);
206
206
  }
207
207
 
208
208
  /**