ripple 0.3.128 → 0.4.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 (192) hide show
  1. package/CHANGELOG.md +267 -0
  2. package/package.json +10 -4
  3. package/src/runtime/element.js +23 -6
  4. package/src/runtime/index-client.js +81 -41
  5. package/src/runtime/index-server.js +1 -0
  6. package/src/runtime/internal/client/blocks.js +173 -91
  7. package/src/runtime/internal/client/component.js +4 -30
  8. package/src/runtime/internal/client/composite.js +12 -13
  9. package/src/runtime/internal/client/constants.js +9 -0
  10. package/src/runtime/internal/client/context.js +12 -19
  11. package/src/runtime/internal/client/css.js +7 -9
  12. package/src/runtime/internal/client/events.js +178 -90
  13. package/src/runtime/internal/client/expression.js +45 -25
  14. package/src/runtime/internal/client/for.js +409 -129
  15. package/src/runtime/internal/client/head.js +10 -5
  16. package/src/runtime/internal/client/html.js +1 -0
  17. package/src/runtime/internal/client/hydration.js +152 -10
  18. package/src/runtime/internal/client/if.js +239 -50
  19. package/src/runtime/internal/client/index.js +4 -12
  20. package/src/runtime/internal/client/operations.js +40 -61
  21. package/src/runtime/internal/client/portal.js +163 -85
  22. package/src/runtime/internal/client/render.js +39 -39
  23. package/src/runtime/internal/client/rpc.js +3 -3
  24. package/src/runtime/internal/client/runtime.js +592 -433
  25. package/src/runtime/internal/client/selector.js +5 -2
  26. package/src/runtime/internal/client/template.js +133 -158
  27. package/src/runtime/internal/client/transport.js +38 -0
  28. package/src/runtime/internal/client/try.js +465 -426
  29. package/src/runtime/internal/client/types.d.ts +56 -23
  30. package/src/runtime/internal/client/utils.js +1 -3
  31. package/src/runtime/internal/server/dynamic.js +20 -21
  32. package/src/runtime/internal/server/index.js +325 -275
  33. package/src/runtime/internal/server/rpc.js +3 -2
  34. package/src/runtime/internal/server/transport.js +16 -0
  35. package/src/runtime/transport.js +21 -0
  36. package/tests/client/__snapshots__/for.test.tsrx.snap +0 -5
  37. package/tests/client/array/array.copy-within.test.tsrx +12 -12
  38. package/tests/client/array/array.derived.test.tsrx +46 -46
  39. package/tests/client/array/array.iteration.test.tsrx +10 -10
  40. package/tests/client/array/array.mutations.test.tsrx +20 -20
  41. package/tests/client/array/array.static.test.tsrx +11 -11
  42. package/tests/client/array/array.to-methods.test.tsrx +6 -6
  43. package/tests/client/async-suspend.test.tsrx +74 -75
  44. package/tests/client/basic/basic.attributes.test.tsrx +86 -83
  45. package/tests/client/basic/basic.collections.test.tsrx +12 -12
  46. package/tests/client/basic/basic.components.test.tsrx +99 -25
  47. package/tests/client/basic/basic.errors.test.tsrx +18 -18
  48. package/tests/client/basic/basic.events.test.tsrx +42 -42
  49. package/tests/client/basic/basic.get-set.test.tsrx +8 -8
  50. package/tests/client/basic/basic.reactivity.test.tsrx +73 -38
  51. package/tests/client/basic/basic.rendering.test.tsrx +25 -25
  52. package/tests/client/basic/basic.utilities.test.tsrx +3 -3
  53. package/tests/client/boundaries.test.tsrx +8 -8
  54. package/tests/client/boxed-locals.test.tsrx +452 -0
  55. package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +6 -6
  56. package/tests/client/compiler/compiler.assignments.test.tsrx +9 -73
  57. package/tests/client/compiler/compiler.attributes.test.tsrx +23 -23
  58. package/tests/client/compiler/compiler.basic.test.tsrx +15 -60
  59. package/tests/client/compiler/compiler.tracked-access.test.tsrx +18 -43
  60. package/tests/client/compiler/compiler.try-in-function.test.tsrx +2 -2
  61. package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -1
  62. package/tests/client/composite/composite.dynamic-components.test.tsrx +77 -6
  63. package/tests/client/composite/composite.props.test.tsrx +149 -12
  64. package/tests/client/composite/composite.reactivity.test.tsrx +51 -52
  65. package/tests/client/composite/composite.render.test.tsrx +26 -9
  66. package/tests/client/css/scoped-styles.test.tsrx +8 -8
  67. package/tests/client/date.test.tsrx +42 -42
  68. package/tests/client/derived-release.test.tsrx +370 -0
  69. package/tests/client/dynamic-elements.test.tsrx +45 -45
  70. package/tests/client/events.test.tsrx +97 -71
  71. package/tests/client/for-selector.test.tsrx +14 -14
  72. package/tests/client/for-single-root-items.test.tsrx +118 -3
  73. package/tests/client/for.test.tsrx +332 -31
  74. package/tests/client/head.test.tsrx +19 -19
  75. package/tests/client/html.test.tsrx +11 -9
  76. package/tests/client/if-block.test.tsrx +80 -0
  77. package/tests/client/map.test.tsrx +16 -16
  78. package/tests/client/media-query.test.tsrx +7 -7
  79. package/tests/client/portal.test.tsrx +224 -26
  80. package/tests/client/primitive-text.test.tsrx +50 -0
  81. package/tests/client/prop-kind-switch.test.tsrx +141 -0
  82. package/tests/client/ref.test.tsrx +17 -17
  83. package/tests/client/return.test.tsrx +26 -3
  84. package/tests/client/root-boundary.test.tsrx +42 -0
  85. package/tests/client/scoped-flush.test.tsrx +8 -8
  86. package/tests/client/set.test.tsrx +6 -6
  87. package/tests/client/svg.test.tsrx +11 -11
  88. package/tests/client/switch.test.tsrx +44 -44
  89. package/tests/client/track-async-hydration.test.tsrx +4 -4
  90. package/tests/client/try.test.tsrx +151 -83
  91. package/tests/client/tsx.test.tsrx +43 -40
  92. package/tests/client/url/url.derived.test.tsrx +6 -6
  93. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +8 -8
  94. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +10 -10
  95. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +10 -10
  96. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +18 -18
  97. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +2 -2
  98. package/tests/hydration/basic.test.js +74 -1
  99. package/tests/hydration/build-components.js +22 -1
  100. package/tests/hydration/compiled/client/basic.js +1142 -713
  101. package/tests/hydration/compiled/client/composite.js +151 -100
  102. package/tests/hydration/compiled/client/events.js +184 -171
  103. package/tests/hydration/compiled/client/for.js +1472 -1132
  104. package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
  105. package/tests/hydration/compiled/client/head.js +254 -201
  106. package/tests/hydration/compiled/client/hmr.js +54 -41
  107. package/tests/hydration/compiled/client/html-in-template.js +54 -39
  108. package/tests/hydration/compiled/client/html.js +1633 -1263
  109. package/tests/hydration/compiled/client/if-children.js +420 -270
  110. package/tests/hydration/compiled/client/if-fragment-controlflow.js +363 -317
  111. package/tests/hydration/compiled/client/if.js +229 -219
  112. package/tests/hydration/compiled/client/mixed-control-flow.js +420 -404
  113. package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1277
  114. package/tests/hydration/compiled/client/portal.js +87 -95
  115. package/tests/hydration/compiled/client/reactivity.js +135 -101
  116. package/tests/hydration/compiled/client/return.js +28 -19
  117. package/tests/hydration/compiled/client/streaming.js +390 -306
  118. package/tests/hydration/compiled/client/switch.js +258 -266
  119. package/tests/hydration/compiled/client/track-async-serialization.js +448 -280
  120. package/tests/hydration/compiled/client/try.js +173 -129
  121. package/tests/hydration/compiled/client/typed-text.js +71 -0
  122. package/tests/hydration/compiled/fixtures/money.js +10 -0
  123. package/tests/hydration/compiled/server/basic.js +123 -6
  124. package/tests/hydration/compiled/server/composite.js +16 -30
  125. package/tests/hydration/compiled/server/events.js +66 -18
  126. package/tests/hydration/compiled/server/for.js +117 -41
  127. package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
  128. package/tests/hydration/compiled/server/head.js +20 -20
  129. package/tests/hydration/compiled/server/hmr.js +2 -2
  130. package/tests/hydration/compiled/server/html.js +70 -238
  131. package/tests/hydration/compiled/server/if-children.js +107 -15
  132. package/tests/hydration/compiled/server/if.js +11 -15
  133. package/tests/hydration/compiled/server/mixed-control-flow.js +8 -8
  134. package/tests/hydration/compiled/server/portal.js +14 -22
  135. package/tests/hydration/compiled/server/reactivity.js +14 -14
  136. package/tests/hydration/compiled/server/streaming.js +19 -19
  137. package/tests/hydration/compiled/server/switch.js +8 -8
  138. package/tests/hydration/compiled/server/track-async-serialization.js +150 -23
  139. package/tests/hydration/compiled/server/try.js +8 -8
  140. package/tests/hydration/compiled/server/typed-text.js +17 -0
  141. package/tests/hydration/components/basic.tsrx +44 -8
  142. package/tests/hydration/components/composite.tsrx +2 -2
  143. package/tests/hydration/components/events.tsrx +25 -25
  144. package/tests/hydration/components/for.tsrx +115 -67
  145. package/tests/hydration/components/fragment-cursor.tsrx +650 -0
  146. package/tests/hydration/components/head.tsrx +16 -16
  147. package/tests/hydration/components/hmr.tsrx +2 -2
  148. package/tests/hydration/components/html.tsrx +7 -7
  149. package/tests/hydration/components/if-children.tsrx +72 -25
  150. package/tests/hydration/components/if.tsrx +18 -18
  151. package/tests/hydration/components/mixed-control-flow.tsrx +11 -11
  152. package/tests/hydration/components/portal.tsrx +3 -3
  153. package/tests/hydration/components/reactivity.tsrx +16 -16
  154. package/tests/hydration/components/streaming.tsrx +20 -20
  155. package/tests/hydration/components/switch.tsrx +20 -20
  156. package/tests/hydration/components/text-types.ts +4 -0
  157. package/tests/hydration/components/track-async-serialization.tsrx +80 -26
  158. package/tests/hydration/components/try.tsrx +8 -8
  159. package/tests/hydration/components/typed-text.tsrx +22 -0
  160. package/tests/hydration/fixtures/money.js +10 -0
  161. package/tests/hydration/for.test.js +36 -0
  162. package/tests/hydration/fragment-cursor.test.js +111 -0
  163. package/tests/hydration/if-children.test.js +24 -0
  164. package/tests/hydration/streaming.test.js +19 -0
  165. package/tests/hydration/track-async-serialization.test.js +87 -2
  166. package/tests/hydration/tsconfig.text-types.json +10 -0
  167. package/tests/hydration/typed-text.test.js +34 -0
  168. package/tests/server/await.test.tsrx +3 -3
  169. package/tests/server/basic.attributes.test.tsrx +42 -42
  170. package/tests/server/basic.components.test.tsrx +64 -8
  171. package/tests/server/basic.test.tsrx +34 -32
  172. package/tests/server/compiler.test.tsrx +1 -70
  173. package/tests/server/composite.props.test.tsrx +6 -6
  174. package/tests/server/dynamic-elements.test.tsrx +31 -8
  175. package/tests/server/for.test.tsrx +94 -0
  176. package/tests/server/head.test.tsrx +11 -11
  177. package/tests/server/scoped-styles.test.tsrx +2 -2
  178. package/tests/server/streaming-ssr.test.tsrx +48 -43
  179. package/tests/server/track-async-serialization.test.tsrx +204 -21
  180. package/tests/server/try.test.tsrx +48 -48
  181. package/tests/types/transport.ts +40 -0
  182. package/tests/utils/vite-plugin-config.test.js +23 -0
  183. package/types/index.d.ts +48 -7
  184. package/types/server.d.ts +3 -0
  185. package/types/transport.d.ts +15 -0
  186. package/src/runtime/internal/client/switch.js +0 -113
  187. package/src/utils/errors.js +0 -13
  188. package/tests/client/lazy-array.test.tsrx +0 -31
  189. package/tests/client/lazy-destructuring.test.tsrx +0 -438
  190. package/tests/client/tracked-index-access.test.tsrx +0 -113
  191. package/tests/server/lazy-destructuring.test.tsrx +0 -595
  192. package/tests/server/tracked-index-access.test.tsrx +0 -76
@@ -3,14 +3,20 @@ import type { Context } from './context.js';
3
3
 
4
4
  export { Tracked, Derived };
5
5
 
6
+ /** One `Context.set` in a component: the context, its value, the parent's chain. */
7
+ export type ContextEntry = {
8
+ k: Context<any>;
9
+ v: any;
10
+ n: null | ContextEntry;
11
+ };
12
+
6
13
  export type Component = {
7
14
  b: null | Block;
8
- c: null | Map<Context<any>, any>;
9
- e: null | Array<{
10
- b: Block;
11
- fn: Function;
12
- r: null | Block | Derived;
13
- }>;
15
+ // The chain of context values set by this component and its ancestors.
16
+ c: null | ContextEntry;
17
+ // Effects deferred until the component has rendered, as flat triples:
18
+ // fn, the block to create it under, the reaction active at the call.
19
+ e: null | Array<Function | Block | Derived | null>;
14
20
  p: null | Component;
15
21
  m: boolean;
16
22
  };
@@ -33,8 +39,15 @@ export type DeferredTrackedEntry = {
33
39
  r: number; // request version id
34
40
  };
35
41
 
42
+ /**
43
+ * Anchor sentinel for one-shot appends at the end of `parent` (all-component
44
+ * children, portal content). Only valid at first render: a block that keeps
45
+ * inserting relative to its anchor must go through `resolve_anchor` first.
46
+ */
36
47
  export type AppendIntoAnchor = {
37
48
  parent: Node;
49
+ /** Marks the sentinel; a missing-property read on a DOM node is cheaper than `in`. */
50
+ into: true;
38
51
  };
39
52
 
40
53
  export type Block = {
@@ -51,25 +64,51 @@ export type Block = {
51
64
  prev: null | Block;
52
65
  s: any;
53
66
  // teardown function
54
- t: (() => {}) | null;
67
+ /** teardown; runtime-internal teardowns receive the block state */
68
+ t: ((state?: any) => void) | null;
55
69
  };
56
70
 
57
- export type TryBoundaryState = {
58
- p: boolean; // whether pending_fn exists
59
- b: () => number; // begin request, returns request id
60
- r: (request_id: number, show_resolved_branch?: boolean) => boolean; // complete request, returns whether the request was active
61
- c: ((error: any) => void) | null; // catch function
62
- rd: (request_id: number, reject_fn: (reason: any) => void) => void; // register deferred reject function
63
- pb: (block: Block) => void; // register paused block
64
- rp: (old_request_id: number) => number; // replace request, returns new request id
71
+ export type TryCatchFunction = (anchor: Node, error: any, reset?: () => void) => void;
72
+ export type TryPendingFunction = (anchor: Node) => void;
73
+
74
+ /**
75
+ * The state of a `@try` block or root boundary. Everything the boundary's
76
+ * pending, catch, request and streaming helpers need lives here, so those
77
+ * helpers are module functions that compile only when a boundary uses them.
78
+ */
79
+ export type TryState = {
80
+ anchor: Node;
81
+ try_fn: (anchor: Node, block?: Block) => void;
82
+ catch_fn: TryCatchFunction | null;
83
+ pending_fn: TryPendingFunction | null;
84
+ /** the catch branch's `reset` callback, created on first use */
85
+ reset: (() => void) | null;
86
+ pending_count: number;
87
+ request_version: number;
88
+ active_requests: Set<number>;
89
+ try_block: Block | null;
90
+ resolved_branch: Block | null;
91
+ pending_branch: Block | null;
92
+ catch_branch: Block | null;
93
+ offscreen_fragment: DocumentFragment | null;
94
+ has_resolved: boolean;
95
+ mode: 'resolved' | 'pending' | 'catch';
96
+ pending_deferreds: Map<number, (reason: any) => void>;
97
+ paused_blocks: Set<Block>;
98
+ /** a streamed slot this boundary hydrated, until its chunk activates it */
99
+ streamed_id: string | null;
100
+ streamed_errored: boolean;
101
+ streamed_fallback: boolean;
102
+ slot_open: Comment | null;
103
+ slot_close: Comment | null;
65
104
  };
66
105
 
67
106
  export type BlockWithTryBoundary = Omit<Block, 's'> & {
68
- s: TryBoundaryState;
107
+ s: TryState;
69
108
  };
70
109
 
71
110
  export type BlockWithTryBoundaryAndCatch = Omit<BlockWithTryBoundary, 's'> & {
72
- s: TryBoundaryState & { c: NonNullable<TryBoundaryState['c']> };
111
+ s: TryState & { catch_fn: TryCatchFunction };
73
112
  };
74
113
 
75
114
  export type RootBoundaryOptions = {
@@ -109,8 +148,6 @@ declare global {
109
148
  value?: string;
110
149
  };
111
150
  __click?: () => void;
112
- // last class value applied by set_class; null once removed
113
- __className?: string | null;
114
151
  __ripple_block?: Block;
115
152
  }
116
153
 
@@ -121,8 +158,4 @@ declare global {
121
158
  interface HTMLSelectElement {
122
159
  __value?: unknown;
123
160
  }
124
-
125
- interface Text {
126
- __t?: string | null;
127
- }
128
161
  }
@@ -5,9 +5,7 @@
5
5
  * @returns {Text}
6
6
  */
7
7
  export function create_anchor() {
8
- var t = document.createTextNode('');
9
- t.__t = '';
10
- return t;
8
+ return document.createTextNode('');
11
9
  }
12
10
 
13
11
  /**
@@ -1,5 +1,4 @@
1
1
  import { is_void_element } from '@tsrx/core/runtime/html';
2
- import { exclude_prop_from_object } from '@tsrx/core/runtime/language-helpers';
3
2
  import {
4
3
  escape,
5
4
  get,
@@ -10,7 +9,6 @@ import {
10
9
  spread_attrs,
11
10
  spread_inner_html,
12
11
  } from './index.js';
13
- import { tsrx_element } from '../../element.js';
14
12
 
15
13
  /**
16
14
  * @param {any} value
@@ -37,7 +35,7 @@ function render_child(value) {
37
35
  */
38
36
  function render_element(tag, props) {
39
37
  output_push(`<${tag}`);
40
- output_push(spread_attrs(props, undefined, 'is'));
38
+ output_push(spread_attrs(props));
41
39
 
42
40
  if (is_void_element(tag)) {
43
41
  output_push(' />');
@@ -57,24 +55,25 @@ function render_element(tag, props) {
57
55
  }
58
56
 
59
57
  /**
60
- * @param {{ is?: Function | string | null | undefined | false, [key: string]: any }} props
61
- * @returns {import('../../element.js').TSRXElement}
58
+ * Renders a dynamic tag (`<{tag} />`): a component function, a tag name, or
59
+ * nothing when the tag is `null`, `undefined`, or `false`. The compiler passes
60
+ * the tag and the element's own props separately, so the props never carry
61
+ * the tag.
62
+ * @param {any} tag
63
+ * @param {Record<string, any>} props
64
+ * @returns {void}
62
65
  */
63
- export function dynamic_element(props) {
64
- return tsrx_element(() => {
65
- const component = get(props?.is);
66
- if (component == null || component === false) {
67
- return;
68
- }
69
-
70
- const dynamic_props = props || {};
66
+ export function dynamic_element(tag, props) {
67
+ const component = get(tag);
68
+ if (component == null || component === false) {
69
+ return;
70
+ }
71
71
 
72
- if (typeof component === 'function') {
73
- render_component(component, exclude_prop_from_object(dynamic_props, 'is'));
74
- } else if (is_tsrx_element(component)) {
75
- throw new TypeError('Invalid component type: received a TSRXElement value.');
76
- } else {
77
- render_element(String(component), dynamic_props);
78
- }
79
- });
72
+ if (typeof component === 'function') {
73
+ render_component(component, props);
74
+ } else if (is_tsrx_element(component)) {
75
+ throw new TypeError('Invalid component type: received a TSRXElement value.');
76
+ } else {
77
+ render_element(String(component), props);
78
+ }
80
79
  }