ripple 0.3.127 → 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 +293 -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 +192 -114
  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 +14 -5
  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 +185 -124
  14. package/src/runtime/internal/client/for.js +616 -264
  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 +9 -13
  20. package/src/runtime/internal/client/operations.js +44 -51
  21. package/src/runtime/internal/client/portal.js +163 -85
  22. package/src/runtime/internal/client/render.js +44 -25
  23. package/src/runtime/internal/client/rpc.js +3 -3
  24. package/src/runtime/internal/client/runtime.js +799 -576
  25. package/src/runtime/internal/client/selector.js +77 -0
  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 +65 -21
  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 +327 -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 +97 -29
  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 +221 -0
  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 +190 -150
  103. package/tests/hydration/compiled/client/for.js +1472 -1126
  104. package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
  105. package/tests/hydration/compiled/client/head.js +255 -199
  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 -400
  113. package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1255
  114. package/tests/hydration/compiled/client/portal.js +87 -95
  115. package/tests/hydration/compiled/client/reactivity.js +140 -83
  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 +19 -19
  126. package/tests/hydration/compiled/server/for.js +109 -49
  127. package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
  128. package/tests/hydration/compiled/server/head.js +20 -28
  129. package/tests/hydration/compiled/server/hmr.js +2 -2
  130. package/tests/hydration/compiled/server/html.js +71 -247
  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 -46
  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,22 +3,35 @@ 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
  };
17
23
 
18
24
  export type Dependency = {
25
+ // clock of the tracked value when it was read
19
26
  c: number;
20
27
  t: Tracked | Derived;
28
+ // next dependency of the same reaction
21
29
  n: null | Dependency;
30
+ // the reaction that read the tracked value
31
+ r: Block | Derived;
32
+ // previous / next subscriber of the same tracked value
33
+ sp: null | Dependency;
34
+ sn: null | Dependency;
22
35
  };
23
36
 
24
37
  export type DeferredTrackedEntry = {
@@ -26,8 +39,15 @@ export type DeferredTrackedEntry = {
26
39
  r: number; // request version id
27
40
  };
28
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
+ */
29
47
  export type AppendIntoAnchor = {
30
48
  parent: Node;
49
+ /** Marks the sentinel; a missing-property read on a DOM node is cheaper than `in`. */
50
+ into: true;
31
51
  };
32
52
 
33
53
  export type Block = {
@@ -36,31 +56,59 @@ export type Block = {
36
56
  first: null | Block;
37
57
  f: number;
38
58
  fn: any;
59
+ // creation id; flushes run scheduled blocks in this order
60
+ i: number;
39
61
  last: null | Block;
40
62
  next: null | Block;
41
63
  p: null | Block;
42
64
  prev: null | Block;
43
65
  s: any;
44
66
  // teardown function
45
- t: (() => {}) | null;
67
+ /** teardown; runtime-internal teardowns receive the block state */
68
+ t: ((state?: any) => void) | null;
46
69
  };
47
70
 
48
- export type TryBoundaryState = {
49
- p: boolean; // whether pending_fn exists
50
- b: () => number; // begin request, returns request id
51
- r: (request_id: number, show_resolved_branch?: boolean) => boolean; // complete request, returns whether the request was active
52
- c: ((error: any) => void) | null; // catch function
53
- rd: (request_id: number, reject_fn: (reason: any) => void) => void; // register deferred reject function
54
- pb: (block: Block) => void; // register paused block
55
- 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;
56
104
  };
57
105
 
58
106
  export type BlockWithTryBoundary = Omit<Block, 's'> & {
59
- s: TryBoundaryState;
107
+ s: TryState;
60
108
  };
61
109
 
62
110
  export type BlockWithTryBoundaryAndCatch = Omit<BlockWithTryBoundary, 's'> & {
63
- s: TryBoundaryState & { c: NonNullable<TryBoundaryState['c']> };
111
+ s: TryState & { catch_fn: TryCatchFunction };
64
112
  };
65
113
 
66
114
  export type RootBoundaryOptions = {
@@ -110,8 +158,4 @@ declare global {
110
158
  interface HTMLSelectElement {
111
159
  __value?: unknown;
112
160
  }
113
-
114
- interface Text {
115
- __t?: string | null;
116
- }
117
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
  }