ripple 0.2.216 → 0.3.0

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 (155) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/package.json +16 -7
  3. package/src/compiler/errors.js +1 -1
  4. package/src/compiler/identifier-utils.js +2 -0
  5. package/src/compiler/index.d.ts +2 -6
  6. package/src/compiler/phases/1-parse/index.js +171 -233
  7. package/src/compiler/phases/2-analyze/index.js +192 -16
  8. package/src/compiler/phases/2-analyze/prune.js +2 -2
  9. package/src/compiler/phases/3-transform/client/index.js +308 -91
  10. package/src/compiler/phases/3-transform/segments.js +43 -15
  11. package/src/compiler/phases/3-transform/server/index.js +71 -21
  12. package/src/compiler/scope.js +31 -12
  13. package/src/compiler/source-map-utils.js +4 -6
  14. package/src/compiler/types/acorn.d.ts +11 -0
  15. package/src/compiler/types/estree-jsx.d.ts +11 -0
  16. package/src/compiler/types/estree.d.ts +11 -0
  17. package/src/compiler/types/import.d.ts +32 -18
  18. package/src/compiler/types/index.d.ts +75 -23
  19. package/src/compiler/types/parse.d.ts +7 -10
  20. package/src/compiler/utils.js +48 -0
  21. package/src/runtime/array.js +53 -22
  22. package/src/runtime/date.js +15 -5
  23. package/src/runtime/index-client.js +41 -7
  24. package/src/runtime/index-server.js +7 -7
  25. package/src/runtime/internal/client/bindings.js +2 -2
  26. package/src/runtime/internal/client/blocks.js +40 -1
  27. package/src/runtime/internal/client/context.js +8 -0
  28. package/src/runtime/internal/client/for.js +3 -3
  29. package/src/runtime/internal/client/index.js +32 -5
  30. package/src/runtime/internal/client/render.js +20 -8
  31. package/src/runtime/internal/client/runtime.js +9 -7
  32. package/src/runtime/internal/client/try.js +15 -22
  33. package/src/runtime/internal/client/utils.js +1 -1
  34. package/src/runtime/internal/server/context.js +8 -0
  35. package/src/runtime/internal/server/index.js +99 -6
  36. package/src/runtime/map.js +7 -7
  37. package/src/runtime/media-query.js +10 -1
  38. package/src/runtime/object.js +6 -6
  39. package/src/runtime/proxy.js +6 -6
  40. package/src/runtime/set.js +11 -11
  41. package/src/runtime/url-search-params.js +13 -2
  42. package/src/runtime/url.js +15 -5
  43. package/src/utils/builders.js +13 -3
  44. package/tests/client/array/array.copy-within.test.ripple +11 -11
  45. package/tests/client/array/array.derived.test.ripple +42 -42
  46. package/tests/client/array/array.iteration.test.ripple +12 -12
  47. package/tests/client/array/array.mutations.test.ripple +25 -25
  48. package/tests/client/array/array.static.test.ripple +103 -106
  49. package/tests/client/array/array.to-methods.test.ripple +8 -8
  50. package/tests/client/async-suspend.test.ripple +94 -0
  51. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  52. package/tests/client/basic/basic.collections.test.ripple +7 -7
  53. package/tests/client/basic/basic.components.test.ripple +48 -10
  54. package/tests/client/basic/basic.errors.test.ripple +46 -31
  55. package/tests/client/basic/basic.events.test.ripple +11 -11
  56. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  57. package/tests/client/basic/basic.reactivity.test.ripple +47 -42
  58. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  59. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  60. package/tests/client/boundaries.test.ripple +7 -7
  61. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +2 -2
  62. package/tests/client/compiler/compiler.assignments.test.ripple +21 -21
  63. package/tests/client/compiler/compiler.basic.test.ripple +223 -82
  64. package/tests/client/compiler/compiler.tracked-access.test.ripple +8 -9
  65. package/tests/client/composite/composite.dynamic-components.test.ripple +8 -8
  66. package/tests/client/composite/composite.generics.test.ripple +4 -4
  67. package/tests/client/composite/composite.props.test.ripple +9 -9
  68. package/tests/client/composite/composite.reactivity.test.ripple +32 -26
  69. package/tests/client/composite/composite.render.test.ripple +13 -4
  70. package/tests/client/computed-properties.test.ripple +3 -3
  71. package/tests/client/context.test.ripple +3 -3
  72. package/tests/client/css/global-additional-cases.test.ripple +4 -4
  73. package/tests/client/css/style-identifier.test.ripple +49 -41
  74. package/tests/client/date.test.ripple +40 -40
  75. package/tests/client/dynamic-elements.test.ripple +165 -30
  76. package/tests/client/events.test.ripple +25 -25
  77. package/tests/client/for.test.ripple +76 -8
  78. package/tests/client/function-overload.test.ripple +0 -1
  79. package/tests/client/head.test.ripple +7 -7
  80. package/tests/client/html.test.ripple +2 -2
  81. package/tests/client/input-value.test.ripple +174 -176
  82. package/tests/client/map.test.ripple +21 -21
  83. package/tests/client/media-query.test.ripple +4 -4
  84. package/tests/client/object.test.ripple +12 -12
  85. package/tests/client/portal.test.ripple +4 -4
  86. package/tests/client/ref.test.ripple +5 -5
  87. package/tests/client/return.test.ripple +17 -17
  88. package/tests/client/set.test.ripple +16 -16
  89. package/tests/client/svg.test.ripple +6 -7
  90. package/tests/client/switch.test.ripple +10 -10
  91. package/tests/client/tracked-expression.test.ripple +1 -3
  92. package/tests/client/try.test.ripple +33 -4
  93. package/tests/client/url/url.derived.test.ripple +10 -9
  94. package/tests/client/url/url.parsing.test.ripple +10 -10
  95. package/tests/client/url/url.partial-removal.test.ripple +10 -10
  96. package/tests/client/url/url.reactivity.test.ripple +17 -17
  97. package/tests/client/url/url.serialization.test.ripple +4 -4
  98. package/tests/client/url-search-params/url-search-params.derived.test.ripple +11 -10
  99. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +5 -7
  100. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +13 -13
  101. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +19 -19
  102. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +17 -17
  103. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +5 -5
  104. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +5 -5
  105. package/tests/hydration/compiled/client/events.js +8 -11
  106. package/tests/hydration/compiled/client/for.js +20 -23
  107. package/tests/hydration/compiled/client/head.js +17 -19
  108. package/tests/hydration/compiled/client/hmr.js +1 -3
  109. package/tests/hydration/compiled/client/html.js +1 -15
  110. package/tests/hydration/compiled/client/if-children.js +7 -9
  111. package/tests/hydration/compiled/client/if.js +5 -7
  112. package/tests/hydration/compiled/client/mixed-control-flow.js +3 -5
  113. package/tests/hydration/compiled/client/portal.js +1 -1
  114. package/tests/hydration/compiled/client/reactivity.js +9 -11
  115. package/tests/hydration/compiled/client/return.js +11 -13
  116. package/tests/hydration/compiled/client/switch.js +4 -6
  117. package/tests/hydration/compiled/server/basic.js +0 -1
  118. package/tests/hydration/compiled/server/composite.js +0 -3
  119. package/tests/hydration/compiled/server/events.js +8 -12
  120. package/tests/hydration/compiled/server/for.js +20 -23
  121. package/tests/hydration/compiled/server/head.js +17 -19
  122. package/tests/hydration/compiled/server/hmr.js +1 -4
  123. package/tests/hydration/compiled/server/html.js +1 -35
  124. package/tests/hydration/compiled/server/if-children.js +7 -11
  125. package/tests/hydration/compiled/server/if.js +5 -7
  126. package/tests/hydration/compiled/server/mixed-control-flow.js +3 -5
  127. package/tests/hydration/compiled/server/portal.js +1 -9
  128. package/tests/hydration/compiled/server/reactivity.js +9 -11
  129. package/tests/hydration/compiled/server/return.js +11 -13
  130. package/tests/hydration/compiled/server/switch.js +4 -6
  131. package/tests/hydration/components/events.ripple +8 -9
  132. package/tests/hydration/components/for.ripple +20 -21
  133. package/tests/hydration/components/head.ripple +6 -8
  134. package/tests/hydration/components/hmr.ripple +1 -2
  135. package/tests/hydration/components/html.ripple +1 -3
  136. package/tests/hydration/components/if-children.ripple +7 -8
  137. package/tests/hydration/components/if.ripple +5 -6
  138. package/tests/hydration/components/mixed-control-flow.ripple +4 -6
  139. package/tests/hydration/components/portal.ripple +1 -1
  140. package/tests/hydration/components/reactivity.ripple +9 -10
  141. package/tests/hydration/components/return.ripple +11 -12
  142. package/tests/hydration/components/switch.ripple +6 -8
  143. package/tests/server/await.test.ripple +2 -2
  144. package/tests/server/basic.attributes.test.ripple +19 -21
  145. package/tests/server/basic.components.test.ripple +13 -7
  146. package/tests/server/basic.test.ripple +20 -21
  147. package/tests/server/compiler.test.ripple +5 -5
  148. package/tests/server/composite.props.test.ripple +6 -7
  149. package/tests/server/composite.test.ripple +4 -4
  150. package/tests/server/context.test.ripple +1 -3
  151. package/tests/server/dynamic-elements.test.ripple +24 -24
  152. package/tests/server/head.test.ripple +5 -7
  153. package/tests/server/style-identifier.test.ripple +16 -17
  154. package/types/index.d.ts +266 -62
  155. package/types/server.d.ts +6 -6
@@ -13,7 +13,25 @@ interface BaseNodeMetaData {
13
13
  scoped?: boolean;
14
14
  path: AST.Node[];
15
15
  has_template?: boolean;
16
- source_name?: string | '#Map' | '#Set' | '#server' | '#style';
16
+ source_name?:
17
+ | string
18
+ | '#ripple'
19
+ | '#ripple.map'
20
+ | '#ripple.set'
21
+ | '#ripple.server'
22
+ | '#ripple.style'
23
+ | '#ripple.array'
24
+ | '#ripple.object'
25
+ | '#ripple.effect'
26
+ | '#ripple.track'
27
+ | '#ripple.trackSplit'
28
+ | '#ripple.untrack'
29
+ | '#ripple.url'
30
+ | '#ripple.urlSearchParams'
31
+ | '#ripple.date'
32
+ | '#ripple.mediaQuery'
33
+ | '#ripple.context'
34
+ | '#ripple.validate';
17
35
  is_capitalized?: boolean;
18
36
  has_await?: boolean;
19
37
  commentContainerId?: number;
@@ -64,8 +82,22 @@ declare module 'estree' {
64
82
  metadata: FunctionMetaData;
65
83
  }
66
84
 
85
+ interface NewExpression {
86
+ metadata: BaseNodeMetaData & {
87
+ skipNewMapping?: boolean;
88
+ };
89
+ }
90
+
91
+ type Accessibility = 'public' | 'protected' | 'private'; // missing in acorn-typescript types
67
92
  interface MethodDefinition {
68
93
  typeParameters?: TSTypeParameterDeclaration;
94
+ accessibility?: Accessibility;
95
+ }
96
+
97
+ interface PropertyDefinition {
98
+ accessibility?: Accessibility;
99
+ readonly?: boolean;
100
+ optional?: boolean;
69
101
  }
70
102
 
71
103
  interface ClassDeclaration {
@@ -85,6 +117,9 @@ declare module 'estree' {
85
117
  // needed for volar tokens to recognize component functions
86
118
  is_component?: boolean;
87
119
  };
120
+ typeAnnotation?: TSTypeAnnotation | undefined;
121
+ decorators: TSESTree.Decorator[];
122
+ optional: boolean;
88
123
  }
89
124
 
90
125
  // We mark the whole node as marked when member is @[expression]
@@ -125,10 +160,8 @@ declare module 'estree' {
125
160
  }
126
161
 
127
162
  interface ExpressionMap {
128
- TrackedArrayExpression: TrackedArrayExpression;
129
- TrackedObjectExpression: TrackedObjectExpression;
130
- TrackedMapExpression: TrackedMapExpression;
131
- TrackedSetExpression: TrackedSetExpression;
163
+ RippleArrayExpression: RippleArrayExpression;
164
+ RippleObjectExpression: RippleObjectExpression;
132
165
  TrackedExpression: TrackedExpression;
133
166
  StyleIdentifier: StyleIdentifier;
134
167
  ServerIdentifier: ServerIdentifier;
@@ -221,6 +254,12 @@ declare module 'estree' {
221
254
  loc: AST.SourceLocation;
222
255
  }
223
256
 
257
+ interface NodeWithMaybeComments {
258
+ innerComments?: AST.Comment[] | undefined;
259
+ leadingComments?: AST.Comment[] | undefined;
260
+ trailingComments?: AST.Comment[] | undefined;
261
+ }
262
+
224
263
  /**
225
264
  * Ripple custom interfaces and types section
226
265
  */
@@ -237,6 +276,7 @@ declare module 'estree' {
237
276
  styleIdentifierPresent?: boolean;
238
277
  };
239
278
  default: boolean;
279
+ typeParameters?: AST.TSTypeParameterDeclaration;
240
280
  }
241
281
 
242
282
  interface TsxCompat extends AST.BaseNode {
@@ -306,7 +346,6 @@ declare module 'estree' {
306
346
  };
307
347
  }
308
348
 
309
- // ScriptContent is only used by Prettier currently
310
349
  interface ScriptContent extends Omit<AST.Element, 'type'> {
311
350
  type: 'ScriptContent';
312
351
  content: string;
@@ -315,8 +354,8 @@ declare module 'estree' {
315
354
  /**
316
355
  * Tracked Expressions
317
356
  */
318
- interface TrackedArrayExpression extends Omit<AST.ArrayExpression, 'type'> {
319
- type: 'TrackedArrayExpression';
357
+ interface RippleArrayExpression extends Omit<AST.ArrayExpression, 'type'> {
358
+ type: 'RippleArrayExpression';
320
359
  elements: (AST.Expression | AST.SpreadElement | null)[];
321
360
  }
322
361
 
@@ -325,21 +364,11 @@ declare module 'estree' {
325
364
  type: 'TrackedExpression';
326
365
  }
327
366
 
328
- interface TrackedObjectExpression extends Omit<AST.ObjectExpression, 'type'> {
329
- type: 'TrackedObjectExpression';
367
+ interface RippleObjectExpression extends Omit<AST.ObjectExpression, 'type'> {
368
+ type: 'RippleObjectExpression';
330
369
  properties: (AST.Property | AST.SpreadElement)[];
331
370
  }
332
371
 
333
- interface TrackedMapExpression extends AST.BaseExpression {
334
- type: 'TrackedMapExpression';
335
- arguments: (AST.Expression | AST.SpreadElement)[];
336
- }
337
-
338
- interface TrackedSetExpression extends AST.BaseExpression {
339
- type: 'TrackedSetExpression';
340
- arguments: (AST.Expression | AST.SpreadElement)[];
341
- }
342
-
343
372
  /**
344
373
  * Ripple attribute nodes
345
374
  */
@@ -399,9 +428,10 @@ declare module 'estree' {
399
428
  export type NodeWithChildren = AST.Element | AST.TsxCompat;
400
429
 
401
430
  export namespace CSS {
402
- export interface BaseNode {
431
+ export interface BaseNode extends AST.NodeWithMaybeComments {
403
432
  start: number;
404
433
  end: number;
434
+ loc?: AST.SourceLocation;
405
435
  }
406
436
 
407
437
  export interface StyleSheet extends BaseNode {
@@ -575,6 +605,9 @@ declare module 'estree-jsx' {
575
605
 
576
606
  interface JSXIdentifier {
577
607
  tracked?: boolean;
608
+ metadata: BaseNodeMetaData & {
609
+ is_component?: boolean;
610
+ };
578
611
  }
579
612
 
580
613
  interface JSXEmptyExpression {
@@ -965,7 +998,7 @@ declare module 'estree' {
965
998
  > {
966
999
  constraint: TypeNode | undefined;
967
1000
  default: TypeNode | undefined;
968
- name: AST.Identifier;
1001
+ name: string; // for some reason acorn-typescript uses string instead of Identifier
969
1002
  }
970
1003
  interface TSTypeParameterDeclaration extends Omit<
971
1004
  AcornTSNode<TSESTree.TSTypeParameterDeclaration>,
@@ -1125,7 +1158,7 @@ export interface Binding {
1125
1158
  metadata: {
1126
1159
  is_dynamic_component?: boolean;
1127
1160
  pattern?: AST.Identifier;
1128
- is_tracked_object?: boolean;
1161
+ is_ripple_object?: boolean;
1129
1162
  } | null;
1130
1163
  /** Kind of binding */
1131
1164
  kind: BindingKind;
@@ -1151,6 +1184,25 @@ export interface ScopeRoot {
1151
1184
  unique(preferred_name: string): AST.Identifier;
1152
1185
  }
1153
1186
 
1187
+ export interface ScopeConstructorInterface {
1188
+ root: ScopeRoot;
1189
+ parent: ScopeInterface | null;
1190
+ porous: boolean;
1191
+ error_options: {
1192
+ loose: boolean;
1193
+ errors: RippleCompileError[];
1194
+ filename: string;
1195
+ comments?: AST.CommentWithLocation[];
1196
+ };
1197
+ }
1198
+
1199
+ export type ScopeConstructorParameters = [
1200
+ root: ScopeConstructorInterface['root'],
1201
+ parent: ScopeConstructorInterface['parent'],
1202
+ porous: ScopeConstructorInterface['porous'],
1203
+ error_options: ScopeConstructorInterface['error_options'],
1204
+ ];
1205
+
1154
1206
  /**
1155
1207
  * Lexical scope for variable bindings
1156
1208
  */
@@ -29,6 +29,7 @@ declare module 'acorn' {
29
29
  line: number;
30
30
  column: number;
31
31
  constructor(line: number, column: number);
32
+ offset(offset: number): Position;
32
33
  }
33
34
  function isNewLine(code: number): boolean;
34
35
 
@@ -929,10 +930,8 @@ export namespace Parse {
929
930
  | AST.ServerIdentifier
930
931
  | AST.StyleIdentifier
931
932
  | AST.TrackedExpression
932
- | AST.TrackedMapExpression
933
- | AST.TrackedSetExpression
934
- | AST.TrackedArrayExpression
935
- | AST.TrackedObjectExpression
933
+ | AST.RippleArrayExpression
934
+ | AST.RippleObjectExpression
936
935
  | AST.Component
937
936
  | AST.Identifier
938
937
  | AST.Literal;
@@ -955,15 +954,11 @@ export namespace Parse {
955
954
  /** Parse parenthesized expression (just the expression) */
956
955
  parseParenExpression(): AST.Expression;
957
956
 
958
- parseTrackedCollectionExpression(
959
- type: 'TrackedMapExpression' | 'TrackedSetExpression',
960
- ): AST.TrackedMapExpression | AST.TrackedSetExpression;
961
-
962
- parseTrackedArrayExpression(): AST.TrackedArrayExpression;
957
+ parseRippleArrayExpression(): AST.RippleArrayExpression;
963
958
 
964
959
  parseTrackedExpression(): AST.TrackedExpression;
965
960
 
966
- parseTrackedObjectExpression(): AST.TrackedObjectExpression;
961
+ parseRippleObjectExpression(): AST.RippleObjectExpression;
967
962
 
968
963
  /**
969
964
  * Parse item in parentheses (can be overridden for flow/ts)
@@ -1131,6 +1126,8 @@ export namespace Parse {
1131
1126
 
1132
1127
  tsCheckTypeAnnotationForReadOnly(node: AST.TSTypeOperator): void;
1133
1128
 
1129
+ tsParseTypeArguments(): AST.Node;
1130
+
1134
1131
  /**
1135
1132
  * Get property kind from name
1136
1133
  * @param prop Property node
@@ -163,6 +163,21 @@ const DOM_PROPERTIES = [
163
163
  'disableRemotePlayback',
164
164
  ];
165
165
 
166
+ /** @type {Record<string, string>} */
167
+ const RIPPLE_NAMESPACE_CALL_NAME = {
168
+ '#ripple.url': 'ripple_url',
169
+ '#ripple.urlSearchParams': 'ripple_url_search_params',
170
+ '#ripple.date': 'ripple_date',
171
+ '#ripple.map': 'ripple_map',
172
+ '#ripple.set': 'ripple_set',
173
+ '#ripple.mediaQuery': 'media_query',
174
+ '#ripple.context': 'context',
175
+ '#ripple.effect': 'effect',
176
+ '#ripple.untrack': 'untrack',
177
+ '#ripple.array': 'ripple_array',
178
+ '#ripple.object': 'ripple_object',
179
+ };
180
+
166
181
  /**
167
182
  * Returns true if name is a DOM property
168
183
  * @param {string} name
@@ -915,3 +930,36 @@ export function flatten_switch_consequent(consequent) {
915
930
  }
916
931
  return result;
917
932
  }
933
+
934
+ /**
935
+ * @param {string | null | undefined} name
936
+ * @returns {string | null}
937
+ */
938
+ export function get_ripple_namespace_call_name(name) {
939
+ return name == null ? null : (RIPPLE_NAMESPACE_CALL_NAME[name] ?? null);
940
+ }
941
+
942
+ /**
943
+ * @param {AST.MemberExpression} member
944
+ * @returns {boolean}
945
+ */
946
+ export function is_property_part_of_ripple_namespace(member) {
947
+ /** @type {AST.MemberExpression | null} */
948
+ let current = member;
949
+
950
+ while (current !== null) {
951
+ const source_name = current.object.metadata?.source_name;
952
+ if (get_ripple_namespace_call_name(source_name) !== null) {
953
+ return true;
954
+ }
955
+
956
+ const parent = current.metadata?.path?.at(-1);
957
+ if (parent?.type !== 'MemberExpression' || parent.object !== current) {
958
+ break;
959
+ }
960
+
961
+ current = parent;
962
+ }
963
+
964
+ return false;
965
+ }
@@ -6,62 +6,93 @@ import { array_proxy } from './proxy.js';
6
6
  * @template T
7
7
  * @constructor
8
8
  * @param {...T} elements
9
- * @returns {TrackedArray<T>}
9
+ * @returns {RippleArray<T>}
10
10
  */
11
- export function TrackedArray(...elements) {
11
+ export function RippleArray(...elements) {
12
12
  if (!new.target) {
13
- throw new Error("TrackedArray must be called with 'new'");
13
+ throw new Error("RippleArray must be called with 'new'");
14
14
  }
15
15
 
16
16
  var block = safe_scope();
17
+ return ripple_array(block, ...elements);
18
+ }
19
+
20
+ /**
21
+ * @template T
22
+ * @param {ArrayLike<T> | Iterable<T>} arrayLike
23
+ * @param {(v: T, k: number) => any | undefined} [mapFn]
24
+ * @param {*} [thisArg]
25
+ * @returns {RippleArray<T>}
26
+ */
27
+ RippleArray.from = function (arrayLike, mapFn, thisArg) {
28
+ return ripple_array.from(safe_scope(), arrayLike, mapFn, thisArg);
29
+ };
30
+
31
+ /**
32
+ * @template T
33
+ * @param {...T} items
34
+ * @returns {RippleArray<T>}
35
+ */
36
+ RippleArray.of = function (...items) {
37
+ return ripple_array.of(safe_scope(), ...items);
38
+ };
39
+
40
+ /**
41
+ * @template T
42
+ * @param {ArrayLike<T> | Iterable<T>} arrayLike
43
+ * @param {(v: T, k: number) => any | undefined} [mapFn]
44
+ * @param {any} [thisArg]
45
+ * @returns {Promise<RippleArray<T>>}
46
+ */
47
+ RippleArray.fromAsync = async function (arrayLike, mapFn, thisArg) {
48
+ return ripple_array.fromAsync(safe_scope(), arrayLike, mapFn, thisArg);
49
+ };
50
+
51
+ /**
52
+ * @template T
53
+ * @param {Block} block
54
+ * @param {...T} elements
55
+ * @returns {RippleArray<T>}
56
+ */
57
+ export function ripple_array(block, ...elements) {
17
58
  return array_proxy({ elements, block });
18
59
  }
19
60
 
20
61
  /**
21
62
  * @template T
63
+ * @param {Block} block
22
64
  * @param {ArrayLike<T> | Iterable<T>} arrayLike
23
65
  * @param {(v: T, k: number) => any | undefined} [mapFn]
24
66
  * @param {*} [thisArg]
25
- * @returns {TrackedArray<T>}
67
+ * @returns {RippleArray<T>}
26
68
  */
27
- TrackedArray.from = function (arrayLike, mapFn, thisArg) {
28
- var block = safe_scope();
69
+ ripple_array.from = function (block, arrayLike, mapFn, thisArg) {
29
70
  var elements = mapFn ? Array.from(arrayLike, mapFn, thisArg) : Array.from(arrayLike);
30
71
  return array_proxy({ elements, block, from_static: true });
31
72
  };
32
73
 
33
74
  /**
34
75
  * @template T
76
+ * @param {Block} block
35
77
  * @param {...T} items
36
- * @returns {TrackedArray<T>}
78
+ * @returns {RippleArray<T>}
37
79
  */
38
- TrackedArray.of = function (...items) {
39
- var block = safe_scope();
80
+ ripple_array.of = function (block, ...items) {
40
81
  var elements = Array.of(...items);
41
82
  return array_proxy({ elements, block, from_static: true });
42
83
  };
43
84
 
44
85
  /**
45
86
  * @template T
87
+ * @param {Block} block
46
88
  * @param {ArrayLike<T> | Iterable<T>} arrayLike
47
89
  * @param {(v: T, k: number) => any | undefined} [mapFn]
48
90
  * @param {any} [thisArg]
49
- * @returns {Promise<TrackedArray<T>>}
91
+ * @returns {Promise<RippleArray<T>>}
50
92
  */
51
- TrackedArray.fromAsync = async function (arrayLike, mapFn, thisArg) {
52
- var block = safe_scope();
93
+ ripple_array.fromAsync = async function (block, arrayLike, mapFn, thisArg) {
53
94
  var elements = mapFn
54
95
  ? await Array.fromAsync(arrayLike, mapFn, thisArg)
55
96
  : await Array.fromAsync(arrayLike);
56
97
  return array_proxy({ elements, block, from_static: true });
57
98
  };
58
-
59
- /**
60
- * @template T
61
- * @param {Array<T>} elements
62
- * @param {Block} block
63
- * @returns {TrackedArray<T>}
64
- */
65
- export function tracked_array(elements, block) {
66
- return array_proxy({ elements, block, from_static: true });
67
- }
@@ -1,18 +1,17 @@
1
1
  /** @import { Block, Derived } from '#client' */
2
- import { safe_scope, tracked, get, derived, set } from './internal/client/runtime.js';
2
+ import { safe_scope, tracked, get, derived, set, with_scope } from './internal/client/runtime.js';
3
3
 
4
4
  var init = false;
5
5
 
6
- export class TrackedDate extends Date {
6
+ export class RippleDate extends Date {
7
7
  #time;
8
8
  /** @type {Map<keyof Date, Derived>} */
9
9
  #deriveds = new Map();
10
10
  /** @type {Block} */
11
11
  #block;
12
12
 
13
- /** @param {any[]} params */
13
+ /** @param {ConstructorParameters<typeof Date>} params */
14
14
  constructor(...params) {
15
- // @ts-ignore
16
15
  super(...params);
17
16
 
18
17
  var block = (this.#block = safe_scope());
@@ -24,7 +23,7 @@ export class TrackedDate extends Date {
24
23
  #init() {
25
24
  init = true;
26
25
 
27
- var proto = TrackedDate.prototype;
26
+ var proto = RippleDate.prototype;
28
27
  var date_proto = Date.prototype;
29
28
 
30
29
  var methods = /** @type {Array<keyof Date & string>} */ (
@@ -71,3 +70,14 @@ export class TrackedDate extends Date {
71
70
  }
72
71
  }
73
72
  }
73
+
74
+ /**
75
+ * @param {Block} block
76
+ * @param {ConstructorParameters<typeof Date>} params
77
+ * @returns {RippleDate}
78
+ */
79
+ export function ripple_date(block, ...params) {
80
+ return with_scope(block, () => {
81
+ return new RippleDate(...params);
82
+ });
83
+ }
@@ -110,19 +110,19 @@ export {
110
110
  tick,
111
111
  } from './internal/client/runtime.js';
112
112
 
113
- export { TrackedArray } from './array.js';
113
+ export { RippleArray } from './array.js';
114
114
 
115
- export { TrackedObject } from './object.js';
115
+ export { RippleObject } from './object.js';
116
116
 
117
- export { TrackedSet } from './set.js';
117
+ export { RippleSet } from './set.js';
118
118
 
119
- export { TrackedMap } from './map.js';
119
+ export { RippleMap } from './map.js';
120
120
 
121
- export { TrackedDate } from './date.js';
121
+ export { RippleDate } from './date.js';
122
122
 
123
- export { TrackedURL } from './url.js';
123
+ export { RippleURL } from './url.js';
124
124
 
125
- export { TrackedURLSearchParams } from './url-search-params.js';
125
+ export { RippleURLSearchParams } from './url-search-params.js';
126
126
 
127
127
  export { createSubscriber } from './create-subscriber.js';
128
128
 
@@ -155,3 +155,37 @@ export {
155
155
  bindOffsetWidth,
156
156
  bindOffsetHeight,
157
157
  } from './internal/client/bindings.js';
158
+
159
+ import { RippleMap } from './map.js';
160
+ import { RippleSet } from './set.js';
161
+ import { RippleArray } from './array.js';
162
+ import { RippleObject } from './object.js';
163
+ import { Context } from './internal/client/context.js';
164
+ import { RippleURL } from './url.js';
165
+ import { RippleURLSearchParams } from './url-search-params.js';
166
+ import { RippleDate } from './date.js';
167
+ import { MediaQuery } from './media-query.js';
168
+ import {
169
+ track,
170
+ track_split as trackSplit,
171
+ untrack,
172
+ ref_prop as createRefKey,
173
+ } from './internal/client/runtime.js';
174
+ import { user_effect as effect } from './internal/client/blocks.js';
175
+
176
+ export const ripple_namespace = {
177
+ map: RippleMap,
178
+ set: RippleSet,
179
+ array: RippleArray,
180
+ object: RippleObject,
181
+ context: Context,
182
+ url: RippleURL,
183
+ urlSearchParams: RippleURLSearchParams,
184
+ date: RippleDate,
185
+ mediaQuery: MediaQuery,
186
+ createRefKey,
187
+ track,
188
+ trackSplit,
189
+ effect,
190
+ untrack,
191
+ };
@@ -12,13 +12,13 @@ export const on = noop;
12
12
  export const tick = noop;
13
13
  export const flushSync = noop;
14
14
 
15
- export const TrackedObject = globalThis.Object;
16
- export const TrackedArray = globalThis.Array;
17
- export const TrackedDate = globalThis.Date;
18
- export const TrackedSet = globalThis.Set;
19
- export const TrackedMap = globalThis.Map;
20
- export const TrackedURL = globalThis.URL;
21
- export const TrackedURLSearchParams = globalThis.URLSearchParams;
15
+ export const RippleObject = globalThis.Object;
16
+ export const RippleArray = globalThis.Array;
17
+ export const RippleDate = globalThis.Date;
18
+ export const RippleSet = globalThis.Set;
19
+ export const RippleMap = globalThis.Map;
20
+ export const RippleURL = globalThis.URL;
21
+ export const RippleURLSearchParams = globalThis.URLSearchParams;
22
22
 
23
23
  /**
24
24
  * @param {string} query A media query string
@@ -10,7 +10,7 @@
10
10
  import { effect, render } from './blocks.js';
11
11
  import { on } from './events.js';
12
12
  import { get, set } from './runtime.js';
13
- import { is_array, is_tracked_object } from './utils.js';
13
+ import { is_array, is_ripple_object } from './utils.js';
14
14
 
15
15
  /**
16
16
  * @param {string} name
@@ -47,7 +47,7 @@ function get_bind_get_set(name, maybe_tracked, set_func) {
47
47
  setter: set_func,
48
48
  };
49
49
  } else {
50
- if (!is_tracked_object(maybe_tracked)) {
50
+ if (!is_ripple_object(maybe_tracked)) {
51
51
  throw not_tracked_type_error(name);
52
52
  }
53
53
 
@@ -369,6 +369,45 @@ export function remove_block_dom(node, end) {
369
369
  }
370
370
  }
371
371
 
372
+ /**
373
+ * Moves DOM nodes from a block to a target element (typically a DocumentFragment).
374
+ * If the block has state (start/end), moves that range.
375
+ * If not, recursively moves content from child branch blocks.
376
+ * @param {Block} block - The block to move content from
377
+ * @param {Element | DocumentFragment} target - Where to move the nodes
378
+ * @returns {boolean} - True if content was moved
379
+ */
380
+ export function move_block(block, target) {
381
+ var f = block.f;
382
+
383
+ // Only BRANCH_BLOCKs (excluding TRY_BLOCK) can have DOM state to move
384
+ if ((f & BRANCH_BLOCK) !== 0 && (f & TRY_BLOCK) === 0) {
385
+ var s = block.s;
386
+ if (s !== null && s.start !== null) {
387
+ var node = s.start;
388
+ var end = s.end;
389
+
390
+ while (node !== null) {
391
+ var next = node === end ? null : next_sibling(node);
392
+ target.append(node);
393
+ node = next;
394
+ }
395
+ return true;
396
+ }
397
+ }
398
+
399
+ // If this block has no DOM, try moving from child branch blocks
400
+ var moved = false;
401
+ var child = block.first;
402
+ while (child !== null) {
403
+ if (move_block(child, target)) {
404
+ moved = true;
405
+ }
406
+ child = child.next;
407
+ }
408
+ return moved;
409
+ }
410
+
372
411
  /**
373
412
  * @param {Block} block
374
413
  * @param {boolean} [remove_dom]
@@ -401,5 +440,5 @@ export function destroy_block(block, remove_dom = true) {
401
440
  unlink_block(block);
402
441
  }
403
442
 
404
- block.fn = block.s = block.d = block.p = block.d = block.co = block.t = null;
443
+ block.fn = block.s = block.d = block.p = block.co = block.t = null;
405
444
  }
@@ -58,3 +58,11 @@ export class Context {
58
58
  current_context.set(context, value);
59
59
  }
60
60
  }
61
+
62
+ /**
63
+ * @template T
64
+ * @param {T} [initial_value]
65
+ */
66
+ export function context(initial_value) {
67
+ return new Context(initial_value);
68
+ }
@@ -436,7 +436,7 @@ function reconcile_by_key(anchor, block, b, render_fn, is_controlled, is_indexed
436
436
  if (fast_path_removal) {
437
437
  fast_path_removal = false;
438
438
  while (i > a_start) {
439
- destroy_block(a[a_start++]);
439
+ destroy_block(a_blocks[a_start++]);
440
440
  }
441
441
  }
442
442
  sources[j - b_start] = i + 1;
@@ -450,7 +450,7 @@ function reconcile_by_key(anchor, block, b, render_fn, is_controlled, is_indexed
450
450
  if (is_indexed) {
451
451
  update_index(block, j);
452
452
  }
453
- update_value(b_block, b_val);
453
+ update_value(block, b_val);
454
454
  ++patched;
455
455
  } else if (!fast_path_removal) {
456
456
  destroy_block(a_blocks[i]);
@@ -694,7 +694,7 @@ function reconcile_by_ref(anchor, block, b, render_fn, is_controlled, is_indexed
694
694
  if (fast_path_removal) {
695
695
  fast_path_removal = false;
696
696
  while (i > a_start) {
697
- destroy_block(a[a_start++]);
697
+ destroy_block(a_blocks[a_start++]);
698
698
  }
699
699
  }
700
700
  sources[j - b_start] = i + 1;