ripple 0.3.6 → 0.3.8

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 (110) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/package.json +2 -2
  3. package/src/compiler/phases/1-parse/index.js +37 -194
  4. package/src/compiler/phases/2-analyze/index.js +290 -26
  5. package/src/compiler/phases/3-transform/client/index.js +54 -14
  6. package/src/compiler/phases/3-transform/server/index.js +19 -35
  7. package/src/compiler/types/index.d.ts +3 -1
  8. package/src/compiler/types/parse.d.ts +0 -8
  9. package/src/compiler/utils.js +10 -6
  10. package/src/runtime/internal/client/composite.js +2 -2
  11. package/src/runtime/internal/client/index.js +2 -0
  12. package/src/runtime/internal/client/runtime.js +95 -45
  13. package/src/runtime/internal/client/types.d.ts +10 -0
  14. package/src/runtime/internal/client/utils.js +12 -0
  15. package/src/runtime/internal/server/index.js +89 -17
  16. package/src/runtime/internal/server/types.d.ts +10 -0
  17. package/src/utils/ast.js +1 -1
  18. package/tests/client/array/array.copy-within.test.ripple +12 -12
  19. package/tests/client/array/array.derived.test.ripple +46 -46
  20. package/tests/client/array/array.iteration.test.ripple +10 -10
  21. package/tests/client/array/array.mutations.test.ripple +20 -20
  22. package/tests/client/array/array.to-methods.test.ripple +6 -6
  23. package/tests/client/async-suspend.test.ripple +5 -5
  24. package/tests/client/basic/basic.attributes.test.ripple +81 -81
  25. package/tests/client/basic/basic.collections.test.ripple +9 -9
  26. package/tests/client/basic/basic.components.test.ripple +28 -28
  27. package/tests/client/basic/basic.errors.test.ripple +18 -18
  28. package/tests/client/basic/basic.events.test.ripple +37 -37
  29. package/tests/client/basic/basic.get-set.test.ripple +6 -6
  30. package/tests/client/basic/basic.reactivity.test.ripple +68 -68
  31. package/tests/client/basic/basic.rendering.test.ripple +19 -19
  32. package/tests/client/basic/basic.utilities.test.ripple +3 -3
  33. package/tests/client/boundaries.test.ripple +12 -12
  34. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
  35. package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
  36. package/tests/client/compiler/compiler.basic.test.ripple +44 -15
  37. package/tests/client/compiler/compiler.tracked-access.test.ripple +68 -2
  38. package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
  39. package/tests/client/composite/composite.props.test.ripple +11 -11
  40. package/tests/client/composite/composite.reactivity.test.ripple +43 -43
  41. package/tests/client/composite/composite.render.test.ripple +3 -3
  42. package/tests/client/computed-properties.test.ripple +4 -4
  43. package/tests/client/date.test.ripple +42 -42
  44. package/tests/client/dynamic-elements.test.ripple +42 -42
  45. package/tests/client/events.test.ripple +70 -70
  46. package/tests/client/for.test.ripple +25 -25
  47. package/tests/client/head.test.ripple +19 -19
  48. package/tests/client/html.test.ripple +3 -3
  49. package/tests/client/input-value.test.ripple +84 -84
  50. package/tests/client/lazy-destructuring.test.ripple +123 -14
  51. package/tests/client/map.test.ripple +16 -16
  52. package/tests/client/media-query.test.ripple +7 -7
  53. package/tests/client/portal.test.ripple +11 -11
  54. package/tests/client/ref.test.ripple +4 -4
  55. package/tests/client/return.test.ripple +52 -52
  56. package/tests/client/set.test.ripple +6 -6
  57. package/tests/client/svg.test.ripple +5 -5
  58. package/tests/client/switch.test.ripple +44 -44
  59. package/tests/client/try.test.ripple +5 -5
  60. package/tests/client/url/url.derived.test.ripple +6 -6
  61. package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
  62. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
  63. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
  64. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
  65. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
  66. package/tests/hydration/compiled/client/events.js +25 -25
  67. package/tests/hydration/compiled/client/for.js +70 -66
  68. package/tests/hydration/compiled/client/head.js +25 -25
  69. package/tests/hydration/compiled/client/hmr.js +2 -2
  70. package/tests/hydration/compiled/client/html.js +3 -3
  71. package/tests/hydration/compiled/client/if-children.js +24 -24
  72. package/tests/hydration/compiled/client/if.js +18 -18
  73. package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
  74. package/tests/hydration/compiled/client/portal.js +3 -3
  75. package/tests/hydration/compiled/client/reactivity.js +16 -16
  76. package/tests/hydration/compiled/client/return.js +40 -40
  77. package/tests/hydration/compiled/client/switch.js +12 -12
  78. package/tests/hydration/compiled/server/events.js +19 -19
  79. package/tests/hydration/compiled/server/for.js +41 -41
  80. package/tests/hydration/compiled/server/head.js +26 -26
  81. package/tests/hydration/compiled/server/hmr.js +2 -2
  82. package/tests/hydration/compiled/server/html.js +2 -2
  83. package/tests/hydration/compiled/server/if-children.js +16 -16
  84. package/tests/hydration/compiled/server/if.js +11 -11
  85. package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
  86. package/tests/hydration/compiled/server/portal.js +2 -2
  87. package/tests/hydration/compiled/server/reactivity.js +16 -16
  88. package/tests/hydration/compiled/server/return.js +25 -25
  89. package/tests/hydration/compiled/server/switch.js +8 -8
  90. package/tests/hydration/components/events.ripple +25 -25
  91. package/tests/hydration/components/for.ripple +66 -66
  92. package/tests/hydration/components/head.ripple +16 -16
  93. package/tests/hydration/components/hmr.ripple +2 -2
  94. package/tests/hydration/components/html.ripple +3 -3
  95. package/tests/hydration/components/if-children.ripple +24 -24
  96. package/tests/hydration/components/if.ripple +18 -18
  97. package/tests/hydration/components/mixed-control-flow.ripple +9 -9
  98. package/tests/hydration/components/portal.ripple +3 -3
  99. package/tests/hydration/components/reactivity.ripple +16 -16
  100. package/tests/hydration/components/return.ripple +40 -40
  101. package/tests/hydration/components/switch.ripple +20 -20
  102. package/tests/server/await.test.ripple +3 -3
  103. package/tests/server/basic.attributes.test.ripple +34 -34
  104. package/tests/server/basic.components.test.ripple +10 -10
  105. package/tests/server/basic.test.ripple +38 -40
  106. package/tests/server/composite.props.test.ripple +9 -9
  107. package/tests/server/dynamic-elements.test.ripple +13 -12
  108. package/tests/server/head.test.ripple +11 -11
  109. package/tests/server/lazy-destructuring.test.ripple +72 -0
  110. package/types/index.d.ts +7 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # ripple
2
2
 
3
+ ## 0.3.8
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies []:
8
+ - ripple@0.3.8
9
+
10
+ ## 0.3.7
11
+
12
+ ### Patch Changes
13
+
14
+ - [#832](https://github.com/Ripple-TS/ripple/pull/832)
15
+ [`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117)
16
+ Thanks [@trueadm](https://github.com/trueadm)! - Fix lazy array rest
17
+ destructuring for tracked and array-like values by routing rest extraction
18
+ through a shared `array_slice` helper instead of calling `.slice()` directly on
19
+ the source.
20
+
21
+ - [#832](https://github.com/Ripple-TS/ripple/pull/832)
22
+ [`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117)
23
+ Thanks [@trueadm](https://github.com/trueadm)! - Allow tracked tuple `.length`
24
+ member access in compiler analysis and simplify tracked direct-access validation
25
+ into a single combined condition.
26
+
27
+ - [#832](https://github.com/Ripple-TS/ripple/pull/832)
28
+ [`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117)
29
+ Thanks [@trueadm](https://github.com/trueadm)! - Fix `to_ts` output for lazy
30
+ array destructuring so it keeps direct destructuring syntax for `track()` and
31
+ `trackSplit()` instead of expanding through an intermediate `lazy` variable.
32
+
33
+ - [#832](https://github.com/Ripple-TS/ripple/pull/832)
34
+ [`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117)
35
+ Thanks [@trueadm](https://github.com/trueadm)! - Replace tracked `get()`/`set()`
36
+ APIs with a `value` getter/setter across runtime, types, analyzer tracked-access
37
+ rules, and lazy destructuring tests.
38
+
39
+ - Updated dependencies
40
+ [[`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117),
41
+ [`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117),
42
+ [`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117),
43
+ [`9ca9310`](https://github.com/Ripple-TS/ripple/commit/9ca9310550a800f4435821ed84b24bdd4f243117)]:
44
+ - ripple@0.3.7
45
+
3
46
  ## 0.3.6
4
47
 
5
48
  ### Patch Changes
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.3.6",
6
+ "version": "0.3.8",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -105,6 +105,6 @@
105
105
  "vscode-languageserver-types": "^3.17.5"
106
106
  },
107
107
  "peerDependencies": {
108
- "ripple": "0.3.6"
108
+ "ripple": "0.3.8"
109
109
  }
110
110
  }
@@ -52,16 +52,6 @@ function DestructuringErrors() {
52
52
  return this;
53
53
  }
54
54
 
55
- /**
56
- * @param {AST.Identifier | ESTreeJSX.JSXIdentifier} node
57
- * @param {string} name
58
- */
59
- function set_tracked_name(node, name) {
60
- node.name = name.slice(1);
61
- node.metadata ??= { path: [] };
62
- node.metadata.source_name = name;
63
- }
64
-
65
55
  /**
66
56
  * Convert JSX node types to regular JavaScript node types
67
57
  * @param {ESTreeJSX.JSXIdentifier | ESTreeJSX.JSXMemberExpression | AST.Node} node - The JSX node to convert
@@ -678,7 +668,7 @@ function RipplePlugin(config) {
678
668
  }
679
669
  if (code === 64) {
680
670
  // @ character
681
- // Look ahead to see if this is followed by a valid identifier character or opening paren
671
+ // Look ahead to see if this is followed by an opening paren
682
672
  if (this.pos + 1 < this.input.length) {
683
673
  const nextChar = this.input.charCodeAt(this.pos + 1);
684
674
 
@@ -688,114 +678,11 @@ function RipplePlugin(config) {
688
678
  this.pos += 2; // skip '@('
689
679
  return this.finishToken(tt.parenL, '@(');
690
680
  }
691
-
692
- // Check if the next character can start an identifier
693
- if (
694
- (nextChar >= 65 && nextChar <= 90) || // A-Z
695
- (nextChar >= 97 && nextChar <= 122) || // a-z
696
- nextChar === 95 ||
697
- nextChar === 36
698
- ) {
699
- // _ or $
700
-
701
- // Check if we're in an expression context
702
- // In JSX expressions, inside parentheses, assignments, etc.
703
- // we want to treat @ as an identifier prefix rather than decorator
704
- const currentType = this.type;
705
- /**
706
- * @param {Parse.TokenType} type
707
- * @param {Parse.Parser} parser
708
- * @param {Parse.TokTypes} tt
709
- * @returns {boolean}
710
- */
711
- function inExpression(type, parser, tt) {
712
- return (
713
- parser.exprAllowed ||
714
- type === tt.braceL || // Inside { }
715
- type === tt.parenL || // Inside ( )
716
- type === tt.eq || // After =
717
- type === tt.comma || // After ,
718
- type === tt.colon || // After :
719
- type === tt.question || // After ?
720
- type === tt.logicalOR || // After ||
721
- type === tt.logicalAND || // After &&
722
- type === tt.dot || // After . (for member expressions like obj.@prop)
723
- type === tt.questionDot // After ?. (for optional chaining like obj?.@prop)
724
- );
725
- }
726
-
727
- /**
728
- * @param {Parse.Parser} parser
729
- * @param {Parse.TokTypes} tt
730
- * @returns {boolean}
731
- */
732
- function inAwait(parser, tt) {
733
- return currentType === tt.name &&
734
- parser.value === 'await' &&
735
- parser.canAwait &&
736
- parser.preToken
737
- ? inExpression(parser.preToken, parser, tt)
738
- : false;
739
- }
740
-
741
- if (inExpression(currentType, this, tt) || inAwait(this, tt)) {
742
- return this.readAtIdentifier();
743
- }
744
- }
745
681
  }
746
682
  }
747
683
  return super.getTokenFromCode(code);
748
684
  }
749
685
 
750
- /**
751
- * Read an @ prefixed identifier
752
- * @type {Parse.Parser['readAtIdentifier']}
753
- */
754
- readAtIdentifier() {
755
- const start = this.pos;
756
- this.pos++; // skip '@'
757
-
758
- // Read the identifier part manually
759
- let word = '';
760
- while (this.pos < this.input.length) {
761
- const ch = this.input.charCodeAt(this.pos);
762
- if (
763
- (ch >= 65 && ch <= 90) || // A-Z
764
- (ch >= 97 && ch <= 122) || // a-z
765
- (ch >= 48 && ch <= 57) || // 0-9
766
- ch === 95 ||
767
- ch === 36
768
- ) {
769
- // _ or $
770
- word += this.input[this.pos++];
771
- } else {
772
- break;
773
- }
774
- }
775
-
776
- if (word === '') {
777
- this.raise(start, 'Invalid @ identifier');
778
- }
779
-
780
- // Return the full identifier including @
781
- return this.finishToken(tt.name, '@' + word);
782
- }
783
-
784
- /**
785
- * Override parseIdent to mark @ identifiers as tracked
786
- * @type {Parse.Parser['parseIdent']}
787
- */
788
- parseIdent(liberal) {
789
- const node = /** @type {AST.Identifier &AST.NodeWithLocation} */ (
790
- super.parseIdent(liberal)
791
- );
792
- if (node.name && node.name.startsWith('@')) {
793
- set_tracked_name(node, node.name);
794
- node.tracked = true;
795
- }
796
- return node;
797
- }
798
-
799
686
  /**
800
687
  * Override parseSubscripts to handle `.@[expression]` syntax for reactive computed member access
801
688
  * @type {Parse.Parser['parseSubscripts']}
@@ -1342,7 +1229,6 @@ function RipplePlugin(config) {
1342
1229
  jsx_parseExpressionContainer() {
1343
1230
  let node = /** @type {ESTreeJSX.JSXExpressionContainer} */ (this.startNode());
1344
1231
  this.next();
1345
- let tracked = false;
1346
1232
 
1347
1233
  if (this.value === 'html') {
1348
1234
  node.html = true;
@@ -1353,20 +1239,12 @@ function RipplePlugin(config) {
1353
1239
  '"html" is a Ripple keyword and must be used in the form {html some_content}',
1354
1240
  );
1355
1241
  }
1356
- if (this.type.label === '@') {
1357
- this.next(); // consume @
1358
- tracked = true;
1359
- }
1360
1242
  }
1361
1243
 
1362
1244
  node.expression =
1363
1245
  this.type === tt.braceR ? this.jsx_parseEmptyExpression() : this.parseExpression();
1364
1246
  this.expect(tt.braceR);
1365
1247
 
1366
- if (tracked && node.expression.type === 'Identifier') {
1367
- node.expression.tracked = true;
1368
- }
1369
-
1370
1248
  return this.finishNode(node, 'JSXExpressionContainer');
1371
1249
  }
1372
1250
 
@@ -1429,10 +1307,6 @@ function RipplePlugin(config) {
1429
1307
  } else {
1430
1308
  const id = /** @type {AST.Identifier} */ (this.parseIdentNode());
1431
1309
  id.tracked = false;
1432
- if (id.name.startsWith('@')) {
1433
- set_tracked_name(id, id.name);
1434
- id.tracked = true;
1435
- }
1436
1310
  this.finishNode(id, 'Identifier');
1437
1311
  /** @type {AST.Attribute} */ (node).name = id;
1438
1312
  /** @type {AST.Attribute} */ (node).value = id;
@@ -1484,14 +1358,6 @@ function RipplePlugin(config) {
1484
1358
  // Unexpected token after @
1485
1359
  this.unexpected();
1486
1360
  }
1487
- } else if (
1488
- (this.type === tt.name || this.type === tstt.jsxName) &&
1489
- this.value &&
1490
- /** @type {string} */ (this.value).startsWith('@')
1491
- ) {
1492
- set_tracked_name(node, /** @type {string} */ (this.value));
1493
- node.tracked = true;
1494
- this.next();
1495
1361
  } else if (this.type === tt.name || this.type.keyword || this.type === tstt.jsxName) {
1496
1362
  node.name = /** @type {string} */ (this.value);
1497
1363
  node.tracked = false; // Explicitly mark as not tracked
@@ -1550,15 +1416,14 @@ function RipplePlugin(config) {
1550
1416
  // Expect closing bracket
1551
1417
  this.expect(tt.bracketR);
1552
1418
  } else {
1553
- // @ not followed by [, treat as regular tracked identifier
1554
- memberExpr.property = this.jsx_parseIdentifier();
1555
- memberExpr.computed = false;
1419
+ this.unexpected();
1556
1420
  }
1557
1421
  } else {
1558
1422
  // Regular dot notation
1559
1423
  memberExpr.property = this.jsx_parseIdentifier();
1560
1424
  memberExpr.computed = false;
1561
1425
  }
1426
+ memberExpr = this.finishNode(memberExpr, 'JSXMemberExpression');
1562
1427
  while (this.eat(tt.dot)) {
1563
1428
  let newMemberExpr = /** @type {ESTreeJSX.JSXMemberExpression} */ (
1564
1429
  this.startNodeAt(
@@ -1571,7 +1436,7 @@ function RipplePlugin(config) {
1571
1436
  newMemberExpr.computed = false;
1572
1437
  memberExpr = this.finishNode(newMemberExpr, 'JSXMemberExpression');
1573
1438
  }
1574
- return this.finishNode(memberExpr, 'JSXMemberExpression');
1439
+ return memberExpr;
1575
1440
  }
1576
1441
  return node;
1577
1442
  }
@@ -2355,53 +2220,6 @@ function RipplePlugin(config) {
2355
2220
  this.awaitPos = 0;
2356
2221
  return this.parseComponent({ requireName: true, declareName: true });
2357
2222
  }
2358
- if (this.type.label === '@') {
2359
- // Try to parse as an expression statement first using tryParse
2360
- // This allows us to handle Ripple @ syntax like @count++ without
2361
- // interfering with legitimate decorator syntax
2362
- this.skip_decorator = true;
2363
- const expressionResult = this.tryParse(() => {
2364
- const node = /** @type {AST.ExpressionStatement} */ (this.startNode());
2365
- this.next();
2366
- // Force expression context to ensure @ is tokenized correctly
2367
- const old_expr_allowed = this.exprAllowed;
2368
- this.exprAllowed = true;
2369
- node.expression = this.parseExpression();
2370
-
2371
- if (node.expression.type === 'UpdateExpression') {
2372
- /** @type {AST.Expression} */
2373
- let object = node.expression.argument;
2374
- while (object.type === 'MemberExpression') {
2375
- object = /** @type {AST.Expression} */ (object.object);
2376
- }
2377
- if (object.type === 'Identifier') {
2378
- object.tracked = true;
2379
- }
2380
- } else if (node.expression.type === 'AssignmentExpression') {
2381
- /** @type {AST.Expression | AST.Pattern | AST.Identifier} */
2382
- let object = node.expression.left;
2383
- while (object.type === 'MemberExpression') {
2384
- object = /** @type {AST.Expression} */ (object.object);
2385
- }
2386
- if (object.type === 'Identifier') {
2387
- object.tracked = true;
2388
- }
2389
- } else if (node.expression.type === 'Identifier') {
2390
- node.expression.tracked = true;
2391
- } else {
2392
- // TODO?
2393
- }
2394
-
2395
- this.exprAllowed = old_expr_allowed;
2396
- return this.finishNode(node, 'ExpressionStatement');
2397
- });
2398
- this.skip_decorator = false;
2399
-
2400
- // If parsing as expression statement succeeded, use that result
2401
- if (expressionResult.node) {
2402
- return expressionResult.node;
2403
- }
2404
- }
2405
2223
 
2406
2224
  if (this.type === tstt.jsxTagStart) {
2407
2225
  this.next();
@@ -2416,6 +2234,37 @@ function RipplePlugin(config) {
2416
2234
  return node;
2417
2235
  }
2418
2236
 
2237
+ // &[ or &{ at statement level — lazy destructuring assignment
2238
+ // e.g., &[data] = track(0); or &{x, y} = obj;
2239
+ if (this.type === tt.bitwiseAND) {
2240
+ const charAfterAmp = this.input.charCodeAt(this.end);
2241
+ if (charAfterAmp === 123 || charAfterAmp === 91) {
2242
+ const node = /** @type {AST.ExpressionStatement} */ (this.startNode());
2243
+ const assign_node = /** @type {AST.AssignmentExpression} */ (this.startNode());
2244
+ this.next(); // consume &
2245
+ // Parse the left-hand side (array or object expression)
2246
+ const left = /** @type {AST.ArrayPattern | AST.ObjectPattern} */ (
2247
+ /** @type {unknown} */ (this.parseExprAtom())
2248
+ );
2249
+ // Convert expression to destructuring pattern
2250
+ this.toAssignable(left, false);
2251
+ left.lazy = true;
2252
+ // Expect = operator
2253
+ this.expect(tt.eq);
2254
+ // Parse the right-hand side
2255
+ assign_node.operator = '=';
2256
+ assign_node.left = left;
2257
+ assign_node.right = /** @type {AST.Expression} */ (this.parseMaybeAssign());
2258
+ node.expression = /** @type {AST.AssignmentExpression} */ (
2259
+ this.finishNode(assign_node, 'AssignmentExpression')
2260
+ );
2261
+ this.semicolon();
2262
+ return /** @type {AST.ExpressionStatement} */ (
2263
+ this.finishNode(node, 'ExpressionStatement')
2264
+ );
2265
+ }
2266
+ }
2267
+
2419
2268
  return super.parseStatement(context, topLevel, exports);
2420
2269
  }
2421
2270
 
@@ -2809,15 +2658,9 @@ function get_comment_handlers(source, comments, index = 0) {
2809
2658
  isSwitchCaseSibling = true;
2810
2659
  } else if (parent.type === 'SwitchCase') {
2811
2660
  node_array = parent.consequent;
2812
- } else if (
2813
- parent.type === 'ArrayExpression' ||
2814
- parent.type === 'RippleArrayExpression'
2815
- ) {
2661
+ } else if (parent.type === 'ArrayExpression') {
2816
2662
  node_array = parent.elements;
2817
- } else if (
2818
- parent.type === 'ObjectExpression' ||
2819
- parent.type === 'RippleObjectExpression'
2820
- ) {
2663
+ } else if (parent.type === 'ObjectExpression') {
2821
2664
  node_array = parent.properties;
2822
2665
  } else if (
2823
2666
  parent.type === 'FunctionDeclaration' ||