ripple 0.2.199 → 0.2.201

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 (55) hide show
  1. package/package.json +5 -4
  2. package/src/compiler/index.d.ts +1 -5
  3. package/src/compiler/phases/1-parse/index.js +145 -11
  4. package/src/compiler/phases/2-analyze/index.js +24 -8
  5. package/src/compiler/phases/2-analyze/prune.js +5 -3
  6. package/src/compiler/phases/3-transform/client/index.js +312 -165
  7. package/src/compiler/phases/3-transform/segments.js +220 -70
  8. package/src/compiler/phases/3-transform/server/index.js +227 -77
  9. package/src/compiler/source-map-utils.js +74 -10
  10. package/src/compiler/types/index.d.ts +63 -21
  11. package/src/compiler/types/parse.d.ts +3 -1
  12. package/src/compiler/utils.js +34 -0
  13. package/src/helpers.d.ts +5 -0
  14. package/src/runtime/index-server.js +27 -47
  15. package/src/runtime/internal/client/composite.js +5 -0
  16. package/src/runtime/internal/client/events.js +1 -9
  17. package/src/runtime/internal/client/for.js +6 -4
  18. package/src/runtime/internal/client/hydration.js +2 -2
  19. package/src/runtime/internal/client/index.js +1 -1
  20. package/src/runtime/internal/client/operations.js +4 -4
  21. package/src/runtime/internal/client/render.js +0 -2
  22. package/src/runtime/internal/client/template.js +9 -1
  23. package/src/runtime/internal/client/types.d.ts +18 -0
  24. package/src/runtime/internal/client/utils.js +1 -1
  25. package/src/runtime/internal/server/index.js +106 -3
  26. package/src/utils/builders.js +25 -5
  27. package/tests/client/basic/basic.attributes.test.ripple +1 -1
  28. package/tests/client/basic/basic.components.test.ripple +47 -0
  29. package/tests/client/basic/basic.rendering.test.ripple +1 -1
  30. package/tests/client/composite/composite.props.test.ripple +49 -4
  31. package/tests/client/dynamic-elements.test.ripple +44 -0
  32. package/tests/client/switch.test.ripple +40 -0
  33. package/tests/client/tsconfig.json +11 -0
  34. package/tests/client.d.ts +5 -22
  35. package/tests/common.d.ts +24 -0
  36. package/tests/hydration/compiled/server/basic.js +109 -24
  37. package/tests/hydration/compiled/server/events.js +161 -72
  38. package/tests/hydration/compiled/server/for.js +202 -102
  39. package/tests/hydration/compiled/server/if.js +130 -50
  40. package/tests/hydration/compiled/server/reactivity.js +51 -12
  41. package/tests/server/__snapshots__/compiler.test.ripple.snap +11 -4
  42. package/tests/server/basic.attributes.test.ripple +459 -0
  43. package/tests/server/basic.components.test.ripple +237 -0
  44. package/tests/server/basic.test.ripple +25 -0
  45. package/tests/server/compiler.test.ripple +2 -3
  46. package/tests/server/composite.props.test.ripple +161 -0
  47. package/tests/server/dynamic-elements.test.ripple +438 -0
  48. package/tests/server/head.test.ripple +102 -0
  49. package/tests/server/switch.test.ripple +40 -0
  50. package/tests/server/tsconfig.json +11 -0
  51. package/tests/server.d.ts +7 -0
  52. package/tests/setup-client.js +6 -2
  53. package/tests/setup-server.js +16 -0
  54. package/types/index.d.ts +2 -2
  55. package/types/server.d.ts +4 -3
@@ -5,6 +5,8 @@ import type { NAMESPACE_URI } from '../../runtime/internal/client/constants.js';
5
5
  import type { Parse } from '#parser';
6
6
  import type * as ESRap from 'esrap';
7
7
  import type { RippleCompileError, CompileOptions } from 'ripple/compiler';
8
+ import type { Position } from 'acorn';
9
+ import type { RequireAllOrNone } from '#helpers';
8
10
 
9
11
  export type RpcModules = Map<string, [string, string]>;
10
12
 
@@ -27,7 +29,9 @@ interface BaseNodeMetaData {
27
29
  }
28
30
 
29
31
  interface FunctionMetaData extends BaseNodeMetaData {
30
- was_component?: boolean;
32
+ // needed for volar tokens to recognize component functions
33
+ is_component?: boolean;
34
+ is_method?: boolean;
31
35
  tracked?: boolean;
32
36
  }
33
37
 
@@ -78,10 +82,23 @@ declare module 'estree' {
78
82
  implements?: AST.TSClassImplements[];
79
83
  }
80
84
 
81
- interface Identifier extends TrackedNode {}
85
+ interface Identifier extends AST.TrackedNode {
86
+ metadata: BaseNodeMetaData & {
87
+ // needed for volar tokens to recognize component functions
88
+ is_component?: boolean;
89
+ };
90
+ }
82
91
 
92
+ // We mark the whole node as marked when member is @[expression]
93
+ // Otherwise, we only mark Identifier nodes
83
94
  interface MemberExpression extends AST.TrackedNode {}
84
95
 
96
+ // These 3 are needed so that Literal can extend TrackedNode
97
+ // since Literal is a union type we have to extend each individually
98
+ interface SimpleLiteral extends AST.TrackedNode {}
99
+ interface RegExpLiteral extends AST.TrackedNode {}
100
+ interface BigIntLiteral extends AST.TrackedNode {}
101
+
85
102
  interface TrackedNode {
86
103
  tracked?: boolean;
87
104
  }
@@ -149,11 +166,11 @@ declare module 'estree' {
149
166
  key?: AST.Expression | null;
150
167
  }
151
168
 
152
- interface ServerIdentifier extends AST.BaseNode {
169
+ interface ServerIdentifier extends AST.BaseExpression {
153
170
  type: 'ServerIdentifier';
154
171
  }
155
172
 
156
- interface StyleIdentifier extends AST.BaseNode {
173
+ interface StyleIdentifier extends AST.BaseExpression {
157
174
  type: 'StyleIdentifier';
158
175
  }
159
176
 
@@ -211,7 +228,6 @@ declare module 'estree' {
211
228
  body: AST.Node[];
212
229
  css: CSS.StyleSheet | null;
213
230
  metadata: BaseNodeMetaData & {
214
- inherited_css?: boolean;
215
231
  topScopedClasses?: TopScopedClasses;
216
232
  styleClasses?: StyleClasses;
217
233
  styleIdentifierPresent?: boolean;
@@ -237,7 +253,8 @@ declare module 'estree' {
237
253
 
238
254
  interface Element extends AST.BaseNode {
239
255
  type: 'Element';
240
- id: AST.Identifier;
256
+ // MemberExpression for namespaced or dynamic elements
257
+ id: AST.Identifier | AST.MemberExpression;
241
258
  attributes: RippleAttribute[];
242
259
  children: AST.Node[];
243
260
  selfClosing?: boolean;
@@ -267,7 +284,7 @@ declare module 'estree' {
267
284
  innerComments?: Comment[];
268
285
  }
269
286
 
270
- export interface TextNode extends AST.BaseNode {
287
+ export interface TextNode extends AST.BaseExpression {
271
288
  type: 'Text';
272
289
  expression: AST.Expression;
273
290
  loc?: AST.SourceLocation;
@@ -299,7 +316,7 @@ declare module 'estree' {
299
316
  elements: (AST.Expression | AST.SpreadElement | null)[];
300
317
  }
301
318
 
302
- interface TrackedExpression extends AST.BaseNode {
319
+ interface TrackedExpression extends AST.BaseExpression {
303
320
  argument: AST.Expression;
304
321
  type: 'TrackedExpression';
305
322
  }
@@ -309,12 +326,12 @@ declare module 'estree' {
309
326
  properties: (AST.Property | AST.SpreadElement)[];
310
327
  }
311
328
 
312
- interface TrackedMapExpression extends AST.BaseNode {
329
+ interface TrackedMapExpression extends AST.BaseExpression {
313
330
  type: 'TrackedMapExpression';
314
331
  arguments: (AST.Expression | AST.SpreadElement)[];
315
332
  }
316
333
 
317
- interface TrackedSetExpression extends AST.BaseNode {
334
+ interface TrackedSetExpression extends AST.BaseExpression {
318
335
  type: 'TrackedSetExpression';
319
336
  arguments: (AST.Expression | AST.SpreadElement)[];
320
337
  }
@@ -365,6 +382,14 @@ declare module 'estree' {
365
382
  body: (Program['body'][number] | Component)[];
366
383
  }
367
384
 
385
+ interface RippleMethodDefinition extends Omit<AST.MethodDefinition, 'value'> {
386
+ value: AST.MethodDefinition['value'] | Component;
387
+ }
388
+
389
+ interface RippleProperty extends Omit<AST.Property, 'value'> {
390
+ value: AST.Property['value'] | Component;
391
+ }
392
+
368
393
  export type RippleAttribute = Attribute | SpreadAttribute | RefAttribute;
369
394
 
370
395
  export namespace CSS {
@@ -569,6 +594,14 @@ declare module 'estree-jsx' {
569
594
  computed?: boolean;
570
595
  }
571
596
 
597
+ interface RippleJSXOpeningElement extends Omit<JSXOpeningElement, 'name'> {
598
+ name: AST.MemberExpression | JSXIdentifier | JSXNamespacedName;
599
+ }
600
+
601
+ interface RippleJSXClosingElement extends Omit<JSXClosingElement, 'name'> {
602
+ name: AST.MemberExpression | JSXIdentifier | JSXNamespacedName;
603
+ }
604
+
572
605
  interface ExpressionMap {
573
606
  JSXIdentifier: JSXIdentifier;
574
607
  }
@@ -678,9 +711,10 @@ declare module 'estree' {
678
711
  interface TSArrayType extends Omit<AcornTSNode<TSESTree.TSArrayType>, 'elementType'> {
679
712
  elementType: TypeNode;
680
713
  }
681
- interface TSAsExpression extends AcornTSNode<TSESTree.TSAsExpression> {
714
+ interface TSAsExpression extends Omit<AcornTSNode<TSESTree.TSAsExpression>, 'typeAnnotation'> {
682
715
  // Have to override it to use our Expression for required properties like metadata
683
716
  expression: AST.Expression;
717
+ typeAnnotation: TypeNode;
684
718
  }
685
719
  interface TSBigIntKeyword extends AcornTSNode<TSESTree.TSBigIntKeyword> {}
686
720
  interface TSBooleanKeyword extends AcornTSNode<TSESTree.TSBooleanKeyword> {}
@@ -865,8 +899,10 @@ declare module 'estree' {
865
899
  interface TSRestType extends Omit<AcornTSNode<TSESTree.TSRestType>, 'typeAnnotation'> {
866
900
  typeAnnotation: TypeNode;
867
901
  }
868
- interface TSSatisfiesExpression extends AcornTSNode<TSESTree.TSSatisfiesExpression> {
902
+ interface TSSatisfiesExpression
903
+ extends Omit<AcornTSNode<TSESTree.TSSatisfiesExpression>, 'typeAnnotation'> {
869
904
  expression: AST.Expression;
905
+ typeAnnotation: TypeNode;
870
906
  }
871
907
  interface TSStringKeyword extends AcornTSNode<TSESTree.TSStringKeyword> {}
872
908
  interface TSSymbolKeyword extends AcornTSNode<TSESTree.TSSymbolKeyword> {}
@@ -961,8 +997,6 @@ declare module 'estree' {
961
997
  }
962
998
  }
963
999
 
964
- import type { Comment, Position } from 'acorn';
965
-
966
1000
  /**
967
1001
  * Parse error information
968
1002
  */
@@ -1175,15 +1209,22 @@ export interface TransformServerState extends BaseState {
1175
1209
  namespace: NameSpace;
1176
1210
  server_block_locals: AST.VariableDeclaration[];
1177
1211
  server_exported_names: string[];
1212
+ dynamicElementName?: AST.TemplateLiteral;
1213
+ applyParentCssScope?: AST.CSS.StyleSheet['hash'];
1178
1214
  }
1179
1215
 
1180
- type UpdateList = Array<{
1181
- identity?: AST.Identifier | AST.Expression;
1182
- initial?: AST.Expression;
1183
- operation: (expr?: AST.Expression, prev?: AST.Expression) => AST.ExpressionStatement;
1184
- expression?: AST.Expression;
1185
- needsPrevTracking?: boolean;
1186
- }> & { async?: boolean };
1216
+ type UpdateList = Array<
1217
+ RequireAllOrNone<
1218
+ {
1219
+ identity?: AST.Identifier | AST.Expression;
1220
+ initial?: AST.Expression;
1221
+ operation: (expr?: AST.Expression, prev?: AST.Expression) => AST.ExpressionStatement;
1222
+ expression?: AST.Expression;
1223
+ needsPrevTracking?: boolean;
1224
+ },
1225
+ 'initial' | 'identity' | 'expression'
1226
+ >
1227
+ > & { async?: boolean };
1187
1228
 
1188
1229
  export interface TransformClientState extends BaseState {
1189
1230
  events: Set<string>;
@@ -1200,6 +1241,7 @@ export interface TransformClientState extends BaseState {
1200
1241
  template: Array<string | AST.Expression> | null;
1201
1242
  update: UpdateList | null;
1202
1243
  errors: RippleCompileError[];
1244
+ applyParentCssScope?: AST.CSS.StyleSheet['hash'];
1203
1245
  }
1204
1246
 
1205
1247
  /** Override zimmerframe types and provide our own */
@@ -934,7 +934,8 @@ export namespace Parse {
934
934
  | AST.TrackedArrayExpression
935
935
  | AST.TrackedObjectExpression
936
936
  | AST.Component
937
- | AST.Identifier;
937
+ | AST.Identifier
938
+ | AST.Literal;
938
939
 
939
940
  /** Default handler for parseExprAtom when no other case matches */
940
941
  parseExprAtomDefault(): AST.Expression;
@@ -1196,6 +1197,7 @@ export namespace Parse {
1196
1197
  requireName?: boolean;
1197
1198
  isDefault?: boolean;
1198
1199
  declareName?: boolean;
1200
+ skipName?: boolean;
1199
1201
  }
1200
1202
  | undefined,
1201
1203
  ): AST.Component;
@@ -584,6 +584,40 @@ export function is_element_dom_element(node) {
584
584
  );
585
585
  }
586
586
 
587
+ /**
588
+ * Returns true if element is a dynamic element
589
+ * @param {AST.Element} node
590
+ * @returns {boolean}
591
+ */
592
+ export function is_element_dynamic(node) {
593
+ return is_id_dynamic(node.id);
594
+ }
595
+
596
+ /**
597
+ * @param {AST.Identifier | AST.MemberExpression | AST.Literal} node
598
+ * @returns {boolean}
599
+ */
600
+ function is_id_dynamic(node) {
601
+ if (node.type === 'Identifier' || node.type === 'Literal') {
602
+ if (node.tracked) {
603
+ return true;
604
+ }
605
+
606
+ return false;
607
+ } else if (node.type === 'MemberExpression') {
608
+ if (/** @type {AST.Identifier} */ (node.object).tracked === true) {
609
+ return true;
610
+ }
611
+ if (node.property.type === 'MemberExpression') {
612
+ return is_id_dynamic(node.property);
613
+ }
614
+
615
+ return !!(/** @type {AST.Identifier} */ (node.property).tracked);
616
+ }
617
+
618
+ return false;
619
+ }
620
+
587
621
  /**
588
622
  * Normalizes children nodes (merges adjacent text, removes empty)
589
623
  * @param {AST.Node[]} children
@@ -0,0 +1,5 @@
1
+ export type RequireAllOrNone<T, K extends keyof T> =
2
+ | (T & Required<Pick<T, K>>)
3
+ | (T & { [P in K]?: never });
4
+
5
+ export type RequiredPresent<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
@@ -1,52 +1,16 @@
1
- /** @import { Component, Derived, Tracked } from '#server' */
2
-
3
- import { DERIVED, TRACKED, UNINITIALIZED } from './internal/client/constants.js';
4
- import { is_tracked_object } from './internal/client/utils.js';
5
- import { active_component, get, set, untrack } from './internal/server/index.js';
1
+ import { get, set, untrack, track, track_split } from './internal/server/index.js';
6
2
 
7
3
  export { Context } from './internal/server/context.js';
8
4
 
9
- export { get, set, untrack };
10
-
11
- export function effect() {
12
- // NO-OP
13
- }
14
-
15
- var empty_get_set = { get: undefined, set: undefined };
16
-
17
- /**
18
- * @param {any} v
19
- * @param {Function} [get]
20
- * @param {Function} [set]
21
- * @returns {Tracked | Derived}
22
- */
23
- export function track(v, get, set) {
24
- var is_tracked = is_tracked_object(v);
25
-
26
- if (is_tracked) {
27
- return v;
28
- }
5
+ export { get, set, untrack, track, track_split as trackSplit };
29
6
 
30
- if (typeof v === 'function') {
31
- return {
32
- a: get || set ? { get, set } : empty_get_set,
33
- c: 0,
34
- co: active_component,
35
- d: null,
36
- f: TRACKED | DERIVED,
37
- fn: v,
38
- v: UNINITIALIZED,
39
- };
40
- }
7
+ function noop() {}
41
8
 
42
- return {
43
- a: get || set ? { get, set } : empty_get_set,
44
- c: 0,
45
- d: null,
46
- f: TRACKED,
47
- v,
48
- };
49
- }
9
+ export const effect = noop;
10
+ export const createRefKey = noop;
11
+ export const on = noop;
12
+ export const tick = noop;
13
+ export const flushSync = noop;
50
14
 
51
15
  export const TrackedObject = globalThis.Object;
52
16
  export const TrackedArray = globalThis.Array;
@@ -72,7 +36,23 @@ export function MediaQuery(query, matches = false) {
72
36
  * @param {any} _
73
37
  */
74
38
  export function createSubscriber(_) {
75
- return () => {
76
- /* NO-OP */
77
- };
39
+ return noop;
78
40
  }
41
+
42
+ export const bindValue = noop;
43
+ export const bindChecked = noop;
44
+ export const bindGroup = noop;
45
+ export const bindClientWidth = noop;
46
+ export const bindClientHeight = noop;
47
+ export const bindContentRect = noop;
48
+ export const bindContentBoxSize = noop;
49
+ export const bindBorderBoxSize = noop;
50
+ export const bindDevicePixelContentBoxSize = noop;
51
+ export const bindFiles = noop;
52
+ export const bindIndeterminate = noop;
53
+ export const bindInnerHTML = noop;
54
+ export const bindInnerText = noop;
55
+ export const bindTextContent = noop;
56
+ export const bindNode = noop;
57
+ export const bindOffsetWidth = noop;
58
+ export const bindOffsetHeight = noop;
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { branch, destroy_block, render, render_spread } from './blocks.js';
4
4
  import { COMPOSITE_BLOCK, DEFAULT_NAMESPACE, NAMESPACE_URI } from './constants.js';
5
+ import { hydrate_next, hydrating } from './hydration.js';
5
6
  import { active_block, active_namespace, with_ns } from './runtime.js';
6
7
  import { top_element_to_ns } from './utils.js';
7
8
 
@@ -13,6 +14,10 @@ import { top_element_to_ns } from './utils.js';
13
14
  * @returns {void}
14
15
  */
15
16
  export function composite(get_component, node, props) {
17
+ if (hydrating) {
18
+ hydrate_next();
19
+ }
20
+
16
21
  var anchor = node;
17
22
  /** @type {Block | null} */
18
23
  var b = null;
@@ -98,20 +98,14 @@ export function handle_event_propagation(event) {
98
98
  // parent of the __root node, which indicates that there's nested
99
99
  // mounted apps. In this case we don't want to trigger events multiple times.
100
100
  var path_idx = 0;
101
-
102
- // @ts-expect-error is added below
103
101
  var handled_at = last_propagated_event === event && event.__root;
104
102
 
105
103
  if (handled_at) {
106
104
  var at_idx = path.indexOf(handled_at);
107
- if (
108
- at_idx !== -1 &&
109
- (handler_element === document || handler_element === /** @type {any} */ (window))
110
- ) {
105
+ if (at_idx !== -1 && (handler_element === document || handler_element === window)) {
111
106
  // This is the fallback document listener or a window listener, but the event was already handled
112
107
  // -> ignore, but set handle_at to document/window so that we're resetting the event
113
108
  // chain in case someone manually dispatches the same event object again.
114
- // @ts-expect-error
115
109
  event.__root = handler_element;
116
110
  return;
117
111
  }
@@ -174,7 +168,6 @@ export function handle_event_propagation(event) {
174
168
  null;
175
169
 
176
170
  try {
177
- // @ts-expect-error
178
171
  var delegated = current_target['__' + event_name];
179
172
 
180
173
  if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
@@ -210,7 +203,6 @@ export function handle_event_propagation(event) {
210
203
  }
211
204
  } finally {
212
205
  set_active_block(previous_block);
213
- // @ts-expect-error is used above
214
206
  event.__root = handler_element;
215
207
  // @ts-ignore remove proxy on currentTarget
216
208
  delete event.currentTarget;
@@ -3,7 +3,7 @@
3
3
  import { IS_CONTROLLED, IS_INDEXED } from '../../../constants.js';
4
4
  import { branch, destroy_block, destroy_block_children, render } from './blocks.js';
5
5
  import { FOR_BLOCK, TRACKED_ARRAY } from './constants.js';
6
- import { hydrate_next, hydrating, set_hydrate_node } from './hydration.js';
6
+ import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from './hydration.js';
7
7
  import { create_text, get_first_child, get_last_child, next_sibling } from './operations.js';
8
8
  import { active_block, set, tracked, untrack } from './runtime.js';
9
9
  import { array_from, is_array } from './utils.js';
@@ -112,11 +112,9 @@ export function for_block(node, get_collection, render_fn, flags) {
112
112
  var anchor = /** @type {Element | Text} */ (node);
113
113
 
114
114
  if (is_controlled) {
115
- var parent_node = /** @type {Element} */ (node);
116
-
117
115
  if (hydrating) {
116
+ var parent_node = /** @type {Element} */ (node);
118
117
  /** @type {Element | Text} */ (set_hydrate_node(get_first_child(parent_node)));
119
- anchor = /** @type {Element | Text} */ (get_last_child(parent_node));
120
118
  } else {
121
119
  anchor = node.appendChild(create_text());
122
120
  }
@@ -135,6 +133,10 @@ export function for_block(node, get_collection, render_fn, flags) {
135
133
  untrack(() => {
136
134
  reconcile_by_ref(anchor, block, array, render_fn, is_controlled, is_indexed);
137
135
  });
136
+
137
+ if (hydrating) {
138
+ anchor = /** @type {Element | Text} */ (hydrate_node);
139
+ }
138
140
  },
139
141
  null,
140
142
  FOR_BLOCK,
@@ -1,5 +1,5 @@
1
- import { HYDRATION_ERROR } from '../../../constants';
2
- import { get_next_sibling } from './operations';
1
+ import { HYDRATION_ERROR } from '../../../constants.js';
2
+ import { get_next_sibling } from './operations.js';
3
3
 
4
4
  export let hydrating = false;
5
5
 
@@ -66,7 +66,7 @@ export { try_block as try, aborted, suspend } from './try.js';
66
66
 
67
67
  export { switch_block as switch } from './switch.js';
68
68
 
69
- export { template, append } from './template.js';
69
+ export { template, append, text } from './template.js';
70
70
 
71
71
  export { tracked_array } from '../../array.js';
72
72
 
@@ -18,7 +18,7 @@ export var is_firefox;
18
18
  export function init_operations() {
19
19
  var node_prototype = Node.prototype;
20
20
  var element_prototype = Element.prototype;
21
- var event_target_prototype = EventTarget.prototype;
21
+ var event_target_prototype = Event.prototype;
22
22
 
23
23
  is_firefox = /Firefox/.test(navigator.userAgent);
24
24
  document = window.document;
@@ -34,9 +34,7 @@ export function init_operations() {
34
34
  );
35
35
 
36
36
  // the following assignments improve perf of lookups on DOM nodes
37
- // @ts-expect-error
38
37
  element_prototype.__click = undefined;
39
- // @ts-expect-error
40
38
  event_target_prototype.__root = undefined;
41
39
  }
42
40
 
@@ -124,7 +122,9 @@ export function next_sibling(node, is_text) {
124
122
  let next_sibling = hydrating ? hydrate_node : node;
125
123
  var last_sibling;
126
124
 
127
- next_sibling = /** @type {ChildNode | null} */ (get_next_sibling(node));
125
+ next_sibling = /** @type {ChildNode | null} */ (
126
+ get_next_sibling(/** @type {ChildNode} */ (next_sibling))
127
+ );
128
128
  last_sibling = next_sibling;
129
129
 
130
130
  if (!hydrating) {
@@ -22,9 +22,7 @@ import { normalize_css_property_name } from '../../../utils/normalize_css_proper
22
22
  export function set_text(text, value) {
23
23
  // For objects, we apply string coercion
24
24
  var str = value == null ? '' : typeof value === 'object' ? value + '' : value;
25
- // @ts-expect-error
26
25
  if (str !== (text.__t ??= text.nodeValue)) {
27
- // @ts-expect-error
28
26
  text.__t = str;
29
27
  text.nodeValue = str + '';
30
28
  }
@@ -7,7 +7,7 @@ import {
7
7
  TEMPLATE_MATHML_NAMESPACE,
8
8
  } from '../../../constants.js';
9
9
  import { hydrate_next, hydrate_node, hydrating, pop } from './hydration.js';
10
- import { get_first_child, is_firefox } from './operations.js';
10
+ import { create_text, get_first_child, is_firefox } from './operations.js';
11
11
  import { active_block, active_namespace } from './runtime.js';
12
12
 
13
13
  /**
@@ -118,6 +118,14 @@ export function append(anchor, dom) {
118
118
  anchor.before(/** @type {Node} */ (dom));
119
119
  }
120
120
 
121
+ export function text(data = '') {
122
+ if (hydrating) {
123
+ assign_nodes(/** @type {Node} */ (hydrate_node), /** @type {Node} */ (hydrate_node));
124
+ return /** @type {Node} */ (hydrate_node);
125
+ }
126
+ return create_text(data);
127
+ }
128
+
121
129
  /**
122
130
  * Create fragment with proper namespace using Svelte's wrapping approach
123
131
  * @param {string} content
@@ -63,3 +63,21 @@ export type CompatApi = {
63
63
  export type CompatOptions = {
64
64
  [key: string]: CompatApi;
65
65
  };
66
+
67
+ declare global {
68
+ interface Element {
69
+ __attributes?: {
70
+ checked?: boolean;
71
+ value?: string;
72
+ };
73
+ __click?: () => void;
74
+ }
75
+
76
+ interface Event {
77
+ __root?: EventTarget;
78
+ }
79
+
80
+ interface Text {
81
+ __t?: string | null;
82
+ }
83
+ }
@@ -33,7 +33,7 @@ export var array_prototype = Array.prototype;
33
33
  */
34
34
  export function create_anchor() {
35
35
  var t = document.createTextNode('');
36
- /** @type {any} */ (t).__t = '';
36
+ t.__t = '';
37
37
  return t;
38
38
  }
39
39